题目描述
在一年前赢得了小镇的最佳草坪比赛后,FJ 变得很懒,再也没有修剪过草坪。现在,新一轮的最佳草坪比赛又开始了,FJ 希望能够再次夺冠。
然而,FJ 的草坪非常脏乱,因此,FJ 只能够让他的奶牛来完成这项工作。FJ 有 N 只排成一排的奶牛,编号为 1...N。每只奶牛的效率是不同的,奶牛 i 的效率为 E_i。
靠近的奶牛们很熟悉,因此,如果 FJ 安排超过 K 只连续的奶牛,那么,这些奶牛就会罢工去开派对:)。现在 FJ 需要你的帮助,计算 FJ 可以得到的最大效率,并且该方案中没有连续的超过 K 只奶牛。
然而,FJ 的草坪非常脏乱,因此,FJ 只能够让他的奶牛来完成这项工作。FJ 有 N 只排成一排的奶牛,编号为 1...N。每只奶牛的效率是不同的,奶牛 i 的效率为 E_i。
靠近的奶牛们很熟悉,因此,如果 FJ 安排超过 K 只连续的奶牛,那么,这些奶牛就会罢工去开派对:)。现在 FJ 需要你的帮助,计算 FJ 可以得到的最大效率,并且该方案中没有连续的超过 K 只奶牛。
输入
第 1 行:空格隔开的两个整数 N 和 K;
第 2 到 N+1 行:第 i+1 行有一个整数 E_i,表示第 i 只奶牛的效率;
第 2 到 N+1 行:第 i+1 行有一个整数 E_i,表示第 i 只奶牛的效率;
输出
输出共一行一行一个整数,表示 FJ 可以得到的最大的效率值。
f[i]表示不选这头牛前i头牛失去的最小效率值,那么状态转移方程f[i]={f[j]+e[i]},其中i-k≤j<i,显然可以单调队列优化,就不会TLE了。
1 #include <cstdio> 2 3 struct node{ 4 int pos; 5 long long v; 6 }que[100001]; 7 8 int l,r,n,k; 9 long long e[100001],f[100001],sum,ans(99999999999999); 10 #define min(x,y) (x<y?x:y) 11 12 int main(void){ 13 scanf("%d%d",&n,&k); 14 for(int i=1;i<=n;++i){ 15 scanf("%lld",&e[i]); 16 sum+=e[i]; 17 } 18 for(int i=1;i<=n;++i){ 19 f[i]=que[l].v+e[i]; 20 while((l<=r)&&(que[l].pos<i-k))++l; 21 while((l<=r)&&(que[r].v>=f[i]))--r; 22 que[++r].pos=i; 23 que[r].v=f[i]; 24 } 25 for(int i=n-k;i<=n;++i) 26 ans=min(ans,f[i]); 27 printf("%lld",sum-ans); 28 }