bzoj 3594
题解见:
http://blog.csdn.net/qpswwww/article/details/44407371
收获:
1、对于一个问题,看似不可做,但一定存在一定特点,我们要做的就是找出一些特点(比如最有解有什么特点,怎样做会尽可能优),尝试强化(加更多的限制)或弱化(减少一些限制)问题看会出现什么新的特征,强化或弱化前有吗,为什么有,为什么没有。
2、DP优化:如果出现dp[i][j] = min( dp[ii][jj]+k | ii<i, jj<j ),可以用数据结构优化(BIT)。
1 /************************************************************** 2 Problem: 3594 3 User: idy002 4 Language: C++ 5 Result: Accepted 6 Time:13408 ms 7 Memory:11844 kb 8 ****************************************************************/ 9 10 #include <cstdio> 11 #define maxn 10010 12 #define maxa 5010 13 #define maxk 510 14 15 int n, k; 16 int ma, mb; 17 int aa[maxn]; 18 int ww[maxa+maxk][maxk]; 19 int dp[maxk]; 20 21 void modify( int a, int b, int val ) { 22 b++; 23 for( int i=a; i<=ma; i+=i&-i ) 24 for( int j=b; j<=mb; j+=j&-j ) 25 if( ww[i][j]<val ) ww[i][j]=val; 26 } 27 int query( int a, int b ) { 28 b++; 29 int rt = 0; 30 for( int i=a; i; i-=i&-i ) 31 for( int j=b; j; j-=j&-j ) 32 if( ww[i][j]>rt ) rt=ww[i][j]; 33 return rt; 34 } 35 36 int main() { 37 scanf( "%d%d", &n, &k ); 38 for( int i=1; i<=n; i++ ) { 39 scanf( "%d", aa+i ); 40 if( aa[i]+k>ma ) ma=aa[i]+k; 41 } 42 mb = k+1; 43 int ans = 0; 44 for( int i=1; i<=n; i++ ) { 45 for( int j=0; j<=k; j++ ) { 46 dp[j] = query( aa[i]+j, j )+1; 47 if( dp[j]>ans ) ans=dp[j]; 48 } 49 for( int j=0; j<=k; j++ ) 50 modify( aa[i]+j, j, dp[j] ); 51 } 52 printf( "%d\n", ans ); 53 }