【BZOJ3594】【SCOI2014】 方伯伯的玉米田

显然可以看出这是一道DP,然后就开始定义状态。。。

f[i][j]表示已经处理完i根玉米,拔高了j次,剩下的玉米的最大值。

f[i][j] = max{f[x][y]+1}(x<i,y<=j,h[x]+y<=h[i]+j)。

于是就可以用二维树状数组维护最大值了,第一维维护拔高次数,第二维维护拔高后的高度。

 1 #include <iostream>
 2 #include <cstdlib>
 3 #include <cstdio>
 4 #include <cstring>
 5 
 6 using namespace std;
 7 
 8 const int N = 10000 + 5;
 9 
10 int n, m, ans, h[N], f[N];
11 
12 struct Tree{
13     int a[5510][510];
14     Tree(){memset( a, 0, sizeof a );}
15     
16     int lowbit( int x ){return x&(-x);}
17     
18     void update( int X, int Y, int d ){
19         for ( int x = X; x <= 5500; x += lowbit(x) )
20             for ( int y = Y; y <= m+1; y += lowbit(y) )
21                 a[x][y] = max( a[x][y],d );
22     }
23     int query( int X, int Y ){
24         int ret = 0;
25         for ( int x = X; x; x -= lowbit(x) )
26             for ( int y = Y; y; y -= lowbit(y) )
27                 ret = max( ret,a[x][y] );
28         return ret;
29     }
30 }T;
31 int main(){
32     scanf( "%d%d", &n, &m );
33     for ( int i = 1; i <= n; i ++ ){
34         int x; scanf( "%d", &x );
35         for ( int j = m; j >= 0; j -- ){
36             f[j] = T.query(x+j,j+1)+1;
37             ans = max( ans,f[j] );
38             T.update(x+j,j+1,f[j]);
39         }
40     }
41     printf( "%d\n", ans );
42     return 0;
43 }
View Code

 

posted @ 2016-02-28 11:04  羁旅  阅读(201)  评论(0编辑  收藏  举报