扑克游戏
题目描述
著名的阳姐•查兰•伊丽莎白一世因为治理国家太有方了,最近国泰民安,阳姐就只能和大黄或者小昊开始玩扑克游戏了。
这个扑克游戏的规则是这样的。
首先,弄出
N
(
将这
N
张牌按照顺序叠成一叠。
两个人轮流抽牌,每次都只能抽现存的最上面的牌或者最下面的牌,并且不放回。
当牌堆被抽光的时候,分数最高的人胜利。
因为女士优先,每次都是阳姐先抽。
阳姐现在想知道,自己能不能赢,最多能得到多少分,自己得到最高分的时候会抽到原牌堆中的哪些牌。(当两种抽法得到的分数相等时,优先取最上面那张牌)
这样说可能会有些不敬,不过由于阳姐出色的(调)教(揉)练,小昊和大黄的智商可以视为极高,也就是说,双方都会执行对自己最有利的抽法。
输入
输入文件名为Poker.ni。
输入第一行一个正整数
第二行顺次包含
N
个数,代表牌堆中最上面的牌一直到最下面的牌的分数。
输出
输出文件名为Joker.ans。
输出第一行为“WIN”或“LOSE”,代表赢或者输。
输出第二行代表阳姐最高的得分。
输出第三行
输入样例
10
8 4 1 6 3 1 9 7 6 6
输出样例
WIN
28
1 10 8 6 4
数据范围
对于
60%
的数据,
1<=N<=100
。
对于
100%
的数据,
1<=N<=1000
,
1<=Wi<=1000
。
Solution
用
fi,j
表示某个人当前要判断从
i
到
则
其中 si,j 等于第 i 张牌到第
Code
#include <iostream>
#include <cstdio>
#define Max(x,y) ((x)>(y)?(x):(y))
using namespace std;
int n;
int w[1010],s[1010];
int f[1010][1010],g[1010][1010],change[1010][1010];
void work(int l,int r){
if(l>r)return;
if((l-r)&1){
printf("%d ",change[l][r]);
if(l==change[l][r])work(l+1,r);
else work(l,r-1);
}
else{
if(l==change[l][r])work(l+1,r);
else work(l,r-1);
}
}
int main(){
freopen("poker.in","r",stdin);
freopen("poker.out","w",stdout);
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&w[i]);
s[i]=s[i-1]+w[i];
}
for(int i=1;i<=n;i++){
g[i][i]=w[i];
change[i][i]=w[i];
}
for(int i=n;i>=1;i--)
for(int j=i+1;j<=n;j++){
if((j-i)&1){
f[i][j]=Max(s[j]-s[i]-g[i+1][j]+w[i],s[j-1]-s[i-1]-g[i][j-1]+w[j]);
if(s[j]-s[i]-g[i+1][j]+w[i]>=s[j-1]-s[i-1]-g[i][j-1]+w[j])change[i][j]=i;
else change[i][j]=j;
}
else{
g[i][j]=Max(s[j]-s[i]-f[i+1][j]+w[i],s[j-1]-s[i-1]-f[i][j-1]+w[j]);
if(s[j]-s[i]-f[i+1][j]+w[i]>=s[j-1]-s[i-1]-f[i][j-1]+w[j])change[i][j]=i;
else change[i][j]=j;
}
}
if(f[1][n]==s[n]-f[1][n]){
printf("PY\n");
}
else if(f[1][n]>s[n]-f[1][n]){
printf("WIN\n");
}
else printf("LOSE\n");
printf("%d\n",f[1][n]);
work(1,n);
return 0;
}