码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2016-04-02 16:01:34      阅读:128      评论:0      收藏:0      [点我收藏+]

标签:

 

【题目链接】

 

    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 }

 

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

标签:

原文地址:http://www.cnblogs.com/lidaxin/p/5347616.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!