tyvj 修剪草坪
2016-01-09 18:43
274 查看
P3980 修剪草坪From: wwqk4444
时间: 1000ms / 空间: 125536KiB / Java类名: Main
约翰让他的奶牛来修建草坪。他有 N 头奶牛,第 i 头奶牛的工作能力为 Ai。编号相近的奶牛很熟悉,如果同时让 K + 1 头编号连在一起的奶牛工作,她们就会密谋罢工。请问,约翰应该让哪些奶牛同时工作,使得它们的能力之和最大,而且不会罢工。
输入格式
• 第一行:两个整数 N 和 K,1 ≤ K ≤ N ≤ 10^5
5
• 第二行到 N + 1 行:第 i + 1 行有一个整数 Ai,1 ≤ Ai ≤ 10^9
9
输出格式
• 单个整数,表示在所有不会罢工的奶牛组合之中,最大的能力之和
样例输入
5 2
1
2
3
4
5
样例输出
12
解释
除了第三头以外的所有奶牛都工作,总能力
为 1 + 2 + 4 + 5 = 12
这是裸DP:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
long long f[110000],a1[110000];
int n,m,i,j,a[110000];
int main()
{
scanf("%d%d",&n,&m);
for (i=1;i<=n;i++)
scanf("%d",&a[i]);
for (i=1;i<=n;i++)
{
a1[i]=a1[i-1]+a[i];//A1中存储的是从1加到i的总和;
}
memset(f,0,sizeof(f));
f[0]=0;
f[1]=a[1];
for (i=2;i<=n;i++)
{
int k=i-m;
for (j=max(k,0);j<=i-1;j++)//枚举上一次断开的点
{
long long l=0;
if (j-1>0)
{
l=f[j-1]+a1[i]-a1[j];
}
else
{
l=a1[i]-a1[j];
}
f[i]=max(f[i],l);
}
}
long long ans=0;
for (i=1;i<=n;i++)
ans=max(ans,f[i]);
printf("%lld",ans);
}//DP方程:f[i]=f[j-1]+a1[i]-a1[j] 观察方程可以发现每次都需要加上a1[i],那么就需要从符合要求的范围内找出最大的f[j-1]-a1[j],这里用单调队列,是优化的关键
这是AC代码
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
long long f[110000],a1[110000],ans;
int n,m,i,j,a[110000];
int head,tail;
long long q[110000],p[110000];//注意数据范围
int main()
{
scanf("%d%d",&n,&m);
for (i=1;i<=n;i++)
scanf("%d",&a[i]);
for (i=1;i<=n;i++)
{
a1[i]=a1[i-1]+a[i];
p[i]=-99999999;
}
head=1; tail=0;
for (i=1;i<=m;i++)
{
f[i]=a1[i];
while(f[i]-a1[i+1]>=p[tail]&&head<=tail) tail--;
p[++tail]=f[i]-a1[i+1];
q[tail]=i;
ans=max(ans,f[i]);
}
for (i=m+1;i<=n;i++)
{
while (i-q[head]-1>m) head++;
f[i]=max(f[i-2]+a1[i]-a1[i-1],p[head]+a1[i]);//这里很重要,之所以加上 f[i-2]+a1[i]-a1[i-1]是因为需要特殊考虑k==1
的情况
while(f[i]-a1[i+1]>=p[tail]&&head<=tail) tail--;
p[++tail]=f[i]-a1[i+1];
q[tail]=i;
ans=max(ans,f[i]);
}
printf("%lld",ans);
}//动态规划+单调队列优化
时间: 1000ms / 空间: 125536KiB / Java类名: Main
描述
约翰让他的奶牛来修建草坪。他有 N 头奶牛,第 i 头奶牛的工作能力为 Ai。编号相近的奶牛很熟悉,如果同时让 K + 1 头编号连在一起的奶牛工作,她们就会密谋罢工。请问,约翰应该让哪些奶牛同时工作,使得它们的能力之和最大,而且不会罢工。输入格式
• 第一行:两个整数 N 和 K,1 ≤ K ≤ N ≤ 10^5
5
• 第二行到 N + 1 行:第 i + 1 行有一个整数 Ai,1 ≤ Ai ≤ 10^9
9
输出格式
• 单个整数,表示在所有不会罢工的奶牛组合之中,最大的能力之和
样例输入
5 2
1
2
3
4
5
样例输出
12
解释
除了第三头以外的所有奶牛都工作,总能力
为 1 + 2 + 4 + 5 = 12
这是裸DP:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
long long f[110000],a1[110000];
int n,m,i,j,a[110000];
int main()
{
scanf("%d%d",&n,&m);
for (i=1;i<=n;i++)
scanf("%d",&a[i]);
for (i=1;i<=n;i++)
{
a1[i]=a1[i-1]+a[i];//A1中存储的是从1加到i的总和;
}
memset(f,0,sizeof(f));
f[0]=0;
f[1]=a[1];
for (i=2;i<=n;i++)
{
int k=i-m;
for (j=max(k,0);j<=i-1;j++)//枚举上一次断开的点
{
long long l=0;
if (j-1>0)
{
l=f[j-1]+a1[i]-a1[j];
}
else
{
l=a1[i]-a1[j];
}
f[i]=max(f[i],l);
}
}
long long ans=0;
for (i=1;i<=n;i++)
ans=max(ans,f[i]);
printf("%lld",ans);
}//DP方程:f[i]=f[j-1]+a1[i]-a1[j] 观察方程可以发现每次都需要加上a1[i],那么就需要从符合要求的范围内找出最大的f[j-1]-a1[j],这里用单调队列,是优化的关键
这是AC代码
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
long long f[110000],a1[110000],ans;
int n,m,i,j,a[110000];
int head,tail;
long long q[110000],p[110000];//注意数据范围
int main()
{
scanf("%d%d",&n,&m);
for (i=1;i<=n;i++)
scanf("%d",&a[i]);
for (i=1;i<=n;i++)
{
a1[i]=a1[i-1]+a[i];
p[i]=-99999999;
}
head=1; tail=0;
for (i=1;i<=m;i++)
{
f[i]=a1[i];
while(f[i]-a1[i+1]>=p[tail]&&head<=tail) tail--;
p[++tail]=f[i]-a1[i+1];
q[tail]=i;
ans=max(ans,f[i]);
}
for (i=m+1;i<=n;i++)
{
while (i-q[head]-1>m) head++;
f[i]=max(f[i-2]+a1[i]-a1[i-1],p[head]+a1[i]);//这里很重要,之所以加上 f[i-2]+a1[i]-a1[i-1]是因为需要特殊考虑k==1
的情况
while(f[i]-a1[i+1]>=p[tail]&&head<=tail) tail--;
p[++tail]=f[i]-a1[i+1];
q[tail]=i;
ans=max(ans,f[i]);
}
printf("%lld",ans);
}//动态规划+单调队列优化
相关文章推荐
- Apple Swift学习资料汇总
- Python入门知识总结
- 我的2015
- C++中cin、cin.get()、cin.getline()、getline()、gets()等
- 2016年关于 Linux 发展趋势的八大预测
- 【Unity闲谈】自动处理2.5D(伪3D)游戏中 物体的遮挡关系
- In MySQL, a zero number equals any string
- 创新声卡在ubuntu中只有左声道有声音的解决方法 。
- MFC中的CDC详细教程(2)
- 解决UITableView分割线距左边有距离的办法
- MFC中如何在不规则的区域内填充颜色
- Linux Core dump
- 关于APUE(Advanced Programming in the Unix Environment)第三版 代码在ubuntu中的编译运行
- SOCKET中send和recv函数工作原理与注意点
- 《Java 核心技术卷一》读书笔记
- 小马哥-----山寨平板10寸 D101主板刷机拆机图与开机界面图 6572双核低配机型
- 【Spring】Spring实战(一)
- 计算机基础--Unicode码和ASCII码的关系
- 解决一bug的流程复盘
- C# 计算字符串在控制台中的显示长度