1 条题解
-
0
题意分析
给定长度为 的序列,两个玩家交替从序列两端取牌,第二玩家固定用贪心策略(总是取两端较大者,平局取左端),第一个玩家可采用任意策略。求在最优对抗下,第二玩家的贪心策略最坏会比第一玩家少多少分。
解题思路
定义 为当前玩家在子区间 上,与对手分数差的最大值。
-
当只剩两张牌时,。
-
否则,当前玩家可先取左端 或右端 :
- 如果先取左端,则对手(贪心)会比较 与 ,取较大者,剩余区间由当前玩家继续获得差值 ;
- 如果先取右端,同理; 取两种选择中差值更大的,即
用二维数组 记忆,最终答案为 。
本题代码
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<limits.h> using namespace std; const int maxn=1100; int dp[maxn][maxn]; int a[maxn],n; int solve(int x,int y) { if(dp[x][y]!=-1) return dp[x][y]; if(x+1==y) return dp[x][y]=abs(a[x]-a[y]); int sa,sb; if(a[x+1]>=a[y])//第一个人选左端 sa=solve(x+2,y)+a[x]-a[x+1]; else sa=solve(x+1,y-1)+a[x]-a[y]; if(a[x]<a[y-1])//第一个人选右端 sb=solve(x,y-2)+a[y]-a[y-1]; else sb=solve(x+1,y-1)+a[y]-a[x]; return dp[x][y]=max(sa,sb); } int main() { int l=0; while(~scanf("%d",&n)&&n) { for(int i=0;i<n;i++) scanf("%d",&a[i]); memset(dp,-1,sizeof(dp)); printf("In game %d, the greedy strategy might lose by as many as %d points.\n",++l,solve(0,n-1)); } return 0; }
-
- 1
信息
- ID
- 1738
- 时间
- 1000ms
- 内存
- 64MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者