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
", ans );
53 }
View Code
原文地址:https://www.cnblogs.com/idy002/p/4350785.html