山东济南彤昌机械科技有限公司 山东济南江鹏工贸游有限公司

bzoj 3594 [Scoi2014]方伯伯的玉米田(DP+二维BIT)

 

【题目链接】

 

    http://www.lydsy.com/JudgeOnline/problem.php?id=3594

 

【题意】

 

    给定一个n个数的序列,有K次将一个区间内的数加1的机会,问最长不下降子序列。

 

【思路】

 

    首先知道每次加1一个区间为[i,n]肯定不会差。

    设f[i][j]为前i个数,还有j次机会的LIS,则有转移式:

        f[i][j] = max{ f[a][b],h[a]+b<=h[i]+j }

    则可以用二维BIT加速方程转移。

 

【代码】

 

 1 #include<set>
 2 #include<cmath>
 3 #include<queue>
 4 #include<vector>
 5 #include<cstdio>
 6 #include<cstring>
 7 #include<iostream>
 8 #include<algorithm>
 9 #define trav(u,i) for(int i=front[u];i;i=e[i].nxt)
10 #define FOR(a,b,c) for(int a=(b);a<=(c);a++)
11 using namespace std;
12 
13 typedef long long ll;
14 const int M = 5600+10;
15 const int N = 500+10;
16 
17 ll read() {
18     char c=getchar();
19     ll f=1,x=0;
20     while(!isdigit(c)) {
21         if(c=='-') f=-1; c=getchar();
22     }
23     while(isdigit(c))
24         x=x*10+c-'0',c=getchar();
25     return x*f;
26 }
27 
28 int C[N][M],n,K,a[10001];
29 
30 int lowbit(int x)
31 {
32     return x&-x;    
33 }
34 void upd(int x,int y,int v)
35 {
36     for(int i=x;i<N;i+=lowbit(i))
37         for(int j=y;j<M;j+=lowbit(j))
38             C[i][j]=max(C[i][j],v);
39 }
40 int query(int x,int y)
41 {
42     int ans=0;
43     for(int i=x;i;i-=lowbit(i))
44         for(int j=y;j;j-=lowbit(j))
45             ans=max(ans,C[i][j]);
46     return ans;
47 }
48 
49 int main()
50 {
51     n=read(),K=read();
52     FOR(i,1,n) a[i]=read();
53     K++;
54     int ans=1;
55     FOR(i,1,n) for(int j=K;j;j--) 
56     {
57         int x=query(j,a[i]+j)+1;
58         ans=max(ans,x);
59         upd(j,a[i]+j,x);
60     }
61     printf("%d\n",ans);
62     return 0;
63 }

 

posted on 2016-04-02 15:15  hahalidaxin  阅读(391)  评论(0编辑  收藏  举报