bzoj3594 [Scoi2014]方伯伯的玉米田
Posted wfj_2048
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj3594 [Scoi2014]方伯伯的玉米田相关的知识,希望对你有一定的参考价值。
Description
方伯伯在自己的农田边散步,他突然发现田里的一排玉米非常的不美。
这排玉米一共有N株,它们的高度参差不齐。
方伯伯认为单调不下降序列很美,所以他决定先把一些玉米拔高,再把破坏美感的玉米拔除掉,使得剩下的玉米的高度构成一个单调不下降序列。
方伯伯可以选择一个区间,把这个区间的玉米全部拔高1单位高度,他可以进行最多K次这样的操作。拔玉米则可以随意选择一个集合的玉米拔掉。
问能最多剩多少株玉米,来构成一排美丽的玉米。
Input
第1行包含2个整数n,K,分别表示这排玉米的数目以及最多可进行多少次操作。
第2行包含n个整数,第i个数表示这排玉米,从左到右第i株玉米的高度ai。
Output
输出1个整数,最多剩下的玉米数。
Sample Input
3 1
2 1 3
2 1 3
Sample Output
3
HINT
1 < N < 10000,1 < K ≤ 500,1 ≤ ai ≤5000
正解:$dp$+二维树状数组优化。
首先有一个显然的结论,就是每次拔玉米肯定是从一个点开始一直拔到$n$,这样肯定是不会差的。
然后我们就可以$dp$了,设$f[i][j]$表示前$i$个点,拔高$j$次玉米的最大玉米数。
然后$dp[i][j]=max(dp[k][p])+1$,当$a[k]\leq a[i]+j-p$时成立。
移项以后可以得到$a[k]+p\leq a[i]+j$,于是我们维护一个二维树状数组的前缀最大值就行了。
1 #include <bits/stdc++.h> 2 #define il inline 3 #define RG register 4 #define ll long long 5 #define lb(x) (x & -x) 6 #define max(a,b) (a>b ? a : b) 7 8 using namespace std; 9 10 int c[6000][510],a[10010],sz,n,k; 11 12 il int gi(){ 13 RG int x=0,q=1; RG char ch=getchar(); 14 while ((ch<‘0‘ || ch>‘9‘) && ch!=‘-‘) ch=getchar(); 15 if (ch==‘-‘) q=-1,ch=getchar(); 16 while (ch>=‘0‘ && ch<=‘9‘) x=x*10+ch-48,ch=getchar(); 17 return q*x; 18 } 19 20 il void add(RG int x,RG int y,RG int v){ 21 for (RG int i=x;i<=sz;i+=lb(i)) 22 for (RG int j=y;j<=k;j+=lb(j)) c[i][j]=max(c[i][j],v); 23 return; 24 } 25 26 il int query(RG int x,RG int y){ 27 RG int res=0; 28 for (RG int i=x;i;i^=lb(i)) 29 for (RG int j=y;j;j^=lb(j)) res=max(res,c[i][j]); 30 return res; 31 } 32 33 int main(){ 34 #ifndef ONLINE_JUDGE 35 freopen("corn.in","r",stdin); 36 freopen("corn.out","w",stdout); 37 #endif 38 n=gi(),k=gi()+1; 39 for (RG int i=1;i<=n;++i) a[i]=gi(),sz=max(sz,a[i]); sz+=k; 40 for (RG int i=1;i<=n;++i) 41 for (RG int j=k;j;--j) add(a[i]+j,j,query(a[i]+j,j)+1); 42 printf("%d\n",query(sz,k)); return 0; 43 }
以上是关于bzoj3594 [Scoi2014]方伯伯的玉米田的主要内容,如果未能解决你的问题,请参考以下文章