题目:
. 修剪草坪
内存限制:512 MiB时间限制:1000 ms标准输入输出
题目类型:传统评测方式:文本比较
题目描述
在一年前赢得了小镇的最佳草坪比赛后,FJ 变得很懒,再也没有修剪过草坪。现在,新一轮的最佳草坪比赛又开始了,FJ 希望能够再次夺冠。
然而,FJ 的草坪非常脏乱,因此,FJ 只能够让他的奶牛来完成这项工作。FJ 有 n 只排成一排的奶牛,编号为 1到 n。每只奶牛的效率是不同的,奶牛 的效率为ei 。
靠近的奶牛们很熟悉,如果 FJ 安排超过 m 只连续的奶牛,那么这些奶牛就会罢工去开派对。因此,现在 FJ 需要你的帮助,计算 FJ 可以得到的最大效率,并且该方案中没有连续的超过 m 只奶牛。
输入格式
第一行:空格隔开的两个整数 n 和m ;
第二到 行:第 i+1 行有一个整数 。
输出格式
一行一个值,表示 FJ 可以得到的最大的效率值。
样例
样例输入
5 2
1
2
3
4
5
样例输出
12
思虑:
这道题就是一道纯粹的转换题,转换之前的题目,转换一下题目,
很容易知道,只需在k+1只奶牛中挑选一只不做就可
代码
#include<iostream>
#include<deque>
#include<climits>
using namespace std;
int n,m;
long long ans=4611686018427387904;
long long summ=0;
long long dp[200005];
long long a[200005];
deque<int> q;
int main()
{
cin>>n>>m;
m++;
for(int i=1;i<=n;i++)
{
cin>>a[i];
summ+=a[i];
}
for(int i=1;i<=m;i++)
{
dp[i]=a[i];
while(!q.empty())
{
if(i-m>q.front())
q.pop_front();
else
break;
}
while(!q.empty())
{
if(dp[q.back()]>dp[i])
q.pop_back();
else
break;
}
q.push_back(i);
}
for(int i=m+1;i<=n;i++)
{
while(!q.empty())
{
if(i-m>q.front())
q.pop_front();
else
break;
}
dp[i]=dp[q.front()]+a[i];
while(!q.empty())
{
if(dp[q.back()]>dp[i])
q.pop_back();
else
break;
}
q.push_back(i);
}
for(int i=n;i>n-m;i--)
ans=min(ans,dp[i]);
cout<<summ-ans;
return 0;
}