JZOJ 1322. 硬币游戏
来源:互联网 发布:酒店网络机顶盒案例 编辑:程序博客网 时间:2024/06/05 20:17
Description
FJ的奶牛喜欢玩硬币游戏,所以FJ发明了一个新的硬币游戏。一开始有N(5<=N<=2,000)个硬币堆成一叠,从上往下数第i个硬币有一个整数值C_i(1<=C_i<=100,000)。
两个玩家轮流从上倒下取硬币,玩家1先取,可以从上面取1个或2个硬币,下一轮的玩家可以取的硬币数量最少为1个,最多为上一个玩家取的数量的2倍,硬币全部取完比赛结束。
已知玩家2绝顶聪明,会采用最优策略,现在请你帮助玩家1,使得玩家1取得的硬币值的和最大。
Input
第一行输入N
第二至N+1行每行输入一个整数C_i
Output
输出玩家1能获得的最大值。
Sample Input
5
1
3
1
7
2
Sample Output
9
Solution
这题显然是一道博弈题(“绝顶聪明”),但是传统的搜索过不了这么大的极限数据。
观察到目标是求极值,于是我们考虑动态规划。
设
F[i][j] 表示还剩余i 个硬币、上一次对手选了j 个硬币的最大获利。再设
sum[i][j] 表示从i 到j 的价值和(可以用前缀和维护)。那么可得转移方程式:
F[i][j]=max{sum[i−k+1][i]+(sum[1][i−k]−F[i−k][k])} 其中:
sum[i−k+1][i] 表示本次自己拿走第i 枚硬币的钱数和;sum[1][i−k]−f[i−k][k] 表示在剩下的局面中自己还能拿的钱数和;1≤k≤min(2∗k,i) 。
于是我们将上式化简,得:
F[i][j]=max{sum[1][i]−F[i−k][k]} (1≤k≤min(2∗k,i)) 但然而这样的 DP 是
O(N3) 的,极限数据会时间超限,要想办法优化成O(N2) 的。继续观察上式,发现两个相邻状态
F[i][j] 和F[i][j−1] 有很多重复的转移,代入可以发现只有两个状态是有用的,即:当
k=2∗j 或k=2∗j−1 时有意义。那么只转移两个状态,时间复杂度就是
O(N2) ,成功通过本题。
Code
#include<cstdio>using namespace std;const int N=2001;int sum[N],f[N][N];inline int read(){ int X=0,w=1; char ch=0; while(ch<'0' || ch>'9') {if(ch=='-') w=-1;ch=getchar();} while(ch>='0' && ch<='9') X=(X<<3)+(X<<1)+ch-'0',ch=getchar(); return X*w;}inline int max(int x,int y){ return x>y?x:y;}int main(){ int n=read(); for(int i=1;i<=n;i++) sum[n-i+1]=read(); for(int i=1;i<=n;i++) sum[i]+=sum[i-1]; for(int i=1;i<=n;i++) for(int j=1;j<=n-i+1;j++) { /*for(int k=1;k<=2*j && k<=i;k++) f[i][j]=max(f[i][j],sum[i]-f[i-k][k]); N^3做法 */ f[i][j]=f[i][j-1]; int k=2*j-1; if(i>=k) f[i][j]=max(f[i][j],sum[i]-f[i-k][k]); if(i>=++k) f[i][j]=max(f[i][j],sum[i]-f[i-k][k]); } printf("%d",f[n][1]); return 0;}
阅读全文
1 0
- JZOJ 1322. 硬币游戏
- JZOJ 1322 硬币游戏
- 硬币游戏
- 硬币游戏
- 硬币游戏
- 抛硬币游戏模拟
- 1349 翻硬币游戏
- 猜硬币游戏设计
- 博弈-翻硬币游戏
- 博弈-翻硬币游戏
- 博弈-翻硬币游戏
- 博弈-翻硬币游戏
- 翻硬币游戏
- 2015京东校招-硬币游戏
- bzoj1411: [ZJOI2009]硬币游戏
- bzoj1411 硬币游戏 分治
- 51nod1381 硬币游戏
- [bzoj4600][SDOI2016]硬币游戏
- 【OpenCV】中的KMeans算法介绍与应用(一)
- 2.2.2特例 基本类型
- 用for循环实现冒泡排序
- Python+Pandas 获取数据库并加入DataFrame
- POJ3281 拆点 最大流 EK算法
- JZOJ 1322. 硬币游戏
- xADC
- 用Wireshark保存RTP的负载码流
- POJ 3254 Corn Fields 状压dp入门
- Servlet基础笔记_17-07-05
- 网络编程(基于winsocket)-- 常用函数介绍(二)
- Scala练习-哈希查找
- 变量-常量
- daemon 进程如何打日志到控制台?