[noip2010模拟] 保龄球
2017-01-22 08:31
267 查看
题目描述
你一个人保龄球馆去打保龄球。总共有k个球可用。每个球的宽度为w。在你前方有n个球棒要打。这n球棒紧密的排成一行,且第i个球棒宽度为1,价值为xi。你的每个球恰能击中第a个~第a+w-1个的球棒(如果此球棒存在的话)。球棒被打到就倒了,且互不影响。你可以向任意方向击球,甚至球的一部分可以越过最左、最右边球棒所构成的边界。求最大价值。输入格式
文件第一行是三个整数n,k,w。以下n行是n个整数,第i个代表x(i)。输出格式
仅一行,为最大价值。样例数据
样例输入
9 2 32
8
5
1
9
6
9
3
2
样例输出
39数据范围
40%的数据满足1≤n,w,k≤100;100%的数据满足1≤n≤10000,1≤w≤100,1≤k≤500;
题目分析
设f[i,j]为用前i个球棒打前j个球,j个球不一定打完,但第j个一定打倒的最大价值。做一次前缀和sum[]
设前一次打到t个保龄球
f[i,j]=f[i-1,t]+sum[j]-sum[j-w] (1<=t<=j-w)
f[i,j]=f[i-1,t]+sum[j]-sum[t] (j-w < t < j)
观察第一个方程,f[i-1,t]最大值在动规过程中即可统计出来。
观察第二个方程,sum[j]是定值,f[i-1,t]-sum[t]可以用单调队列维护最大值。
故O(nk)解决此题
源代码
#include<algorithm> #include<iostream> #include<iomanip> #include<cstring> #include<cstdlib> #include<vector> #include<cstdio> #include<cmath> #include<queue> using namespace std; inline const int Get_Int() { int num=0,bj=1; char x=getchar(); while(x<'0'||x>'9') { if(x=='-')bj=-1; x=getchar(); } while(x>='0'&&x<='9') { num=num*10+x-'0'; x=getchar(); } return num*bj; } int n,k,w,sum[15005],f[505][15005],ans=0; int main() { n=Get_Int(); k=Get_Int(); w=Get_Int(); for(int i=1; i<=n; i++)sum[i]=sum[i-1]+Get_Int(); for(int i=n+1; i<=n+w; i++)sum[i]=sum[i-1]; for(int i=1; i<=n+w; i++)f[1][i]=sum[i]-sum[max(i-w,0)]; for(int i=2; i<=k; i++) { //打k次保龄球 int Max=-0x7fffffff/2; deque<int>Q; Q.push_back(0); for(int j=1; j<=n+w; j++) { while(!Q.empty()&&Q.front()<j-w)Q.pop_front(); //维护队首 if(j-w>=0)Max=max(Max,f[i-1][j-w]); //将方程1的最大值维护走 f[i][j]=max(f[i-1][Q.front()]-sum[Q.front()],Max-sum[j-w])+sum[j]; while(!Q.empty()&&f[i-1][Q.back()]-sum[Q.back()]<=f[i-1][j]-sum[j])Q.pop_back(); //维护队尾 Q.push_back(j); ans=max(ans,f[i][j]); } } printf("%d\n",ans); return 0; }
相关文章推荐
- [模拟][NOIP2010] 机器翻译
- 【图-最小生成树】NOIP2010 模拟试题 新的开始
- noip2010 机器翻译 (模拟)
- NOIP2010-普及组复赛模拟试题-第一题-手机
- NOIP2010-普及组复赛模拟试题-第二题-数字积木
- 【模拟】【NOIP2010】机器翻译 translate
- noip2010 接水问题 (模拟)
- 【NOIP2010】【模拟】T1 机器翻译 题解
- 【模拟】【NOIP2010】机器翻译 translate
- 中山纪念中学 NOIP2010模拟赛
- NOIP提高组2010-2015初赛+模拟2
- [NOIP2010]三国游戏 T4 模拟
- [NOIP2010]机器翻译 队列+模拟
- VS 2010 MFC 制作的双色球模拟软件 之 dlg.cpp
- JZOJ5373. 【NOIP2017提高A组模拟9.17】信仰是为了虚无之人
- bzoj 1972: [Sdoi2010]猪国杀 (大模拟)
- NOIP模拟 NYG的背包 [高山算法]
- NOIPの模拟_2016_8_11_t2_种树
- 【NOIP2011模拟9.3】跳舞 (Standard IO)
- JZOJ 5195. 【NOIP2017提高组模拟7.3】A