NOIP模拟(20171030)T2 游戏
2017-11-01 08:41
495 查看
n个物品,每个物品权值为ai(1≤i≤n),两人按给定顺序轮流拿物品,先手先拿1或2个物品。然后若上一个人拿了k个物品,这一个人必须拿k或k+1个物品,若剩余物品不足k个,游戏结束。
两个人都尽可能使自己拿的权值比别人大,游戏结束后,先手拿的权值比后手多多少(假设两个人都绝顶聪明)那还要我干嘛
n≤20000
考虑dp:dp[i][j] 表示现在从第i个物品开始拿,上一个人拿了j 个,能使自己比对方多拿权值的最大值,则:
dp[i][j]=max(sum[i+j−1]−dp[i+j][j],sum[i+j]−dp[i+j+1][j+1]))−sum[i−1]
然后注意j 是 O(i√)级别的,否则会MLE
两个人都尽可能使自己拿的权值比别人大,游戏结束后,先手拿的权值比后手多多少(假设两个人都绝顶聪明)那还要我干嘛
n≤20000
考虑dp:dp[i][j] 表示现在从第i个物品开始拿,上一个人拿了j 个,能使自己比对方多拿权值的最大值,则:
dp[i][j]=max(sum[i+j−1]−dp[i+j][j],sum[i+j]−dp[i+j+1][j+1]))−sum[i−1]
然后注意j 是 O(i√)级别的,否则会MLE
#include<bits/stdc++.h> using namespace std; inline int getint(){ int x=0,p=1; char c=getchar(); while(!isdigit(c)){ if(c=='-')p=-1; c=getchar(); } while(isdigit(c)){ x=(x<<3)+(x<<1)+(c^'0'); c=getchar(); } return x*p; } int dp[20005][205]; int sum[20005]; inline void work(){ int n=getint(); memset(dp,0,sizeof(dp)); memset(sum,0,sizeof(sum)); for(int i=1;i<=n;++i){ sum[i]=sum[i-1]+getint(); } sum[n+1]=-0x3fffffff; for(int i=n;i>=1;--i){ int top,s=0; for(top=0;s<=i;++top,s+=top); for(int j=top;j;--j){ if(i+j-1>n)continue; dp[i][j]=max(sum[i+j-1]-dp[i+j][j],sum[i+j]-dp[i+j+1][j+1])-sum[i-1]; } } // for(int i=1;i<=n;++i){ // for(int j=1;j<=3;++j){ // cout<<i<<" "<<j<<" "<<dp[i][j]<<endl; // } // } cout<<dp[1][1]<<"\n"; } int main(){ int t=getint(); while(t--){ work(); } return 0; }
相关文章推荐
- 密码游戏 - bzoj十连测 Test7 T2
- NOIP模拟(20171024)T2 乘积
- NOIP模拟(20171102)T2 最佳序列
- bzoj1854: [Scoi2010]游戏(匈牙利) / GDKOI Day2 T2(最大流)
- (noip模拟 约瑟夫游戏)<神**乱搞题>
- NOIP模拟(10.20)T2 矩阵(bzoj1084 最大子矩阵)
- NOIP模拟(10.23)T2 一样远
- NOIP模拟(11.06)T2 序列操作
- NOIP2013 D1 T2 国王游戏
- NOIP模拟(20171026)T2 做运动
- NOIP模拟(11.02)T2 最佳序列
- 【贪心+高精度】NOIP2012D1T2国王游戏Codevs1198
- 开学能力测试t2 删点游戏
- NOIP模拟(20171023)T2 一样远
- NOIP模拟(10.30)T2 Game
- NOIP模拟(11.02)T4 赌博游戏
- NOIP 2012 提高组 DAY1 T2 国王游戏
- NOIP模拟(10.31)T2 朋友 (bzoj2143 飞飞侠)
- SNOI省选模拟赛Round3 T2 游戏game 最小割
- 一中OJ #3529 解密游戏 [南开OJ P3824 重庆市四校联考T2] | 动态规划 + Trie树优化 | 解题报告