扑克游戏

69 篇文章 0 订阅

扑克游戏


题目描述

著名的阳姐•查兰•伊丽莎白一世因为治理国家太有方了,最近国泰民安,阳姐就只能和大黄或者小昊开始玩扑克游戏了。
这个扑克游戏的规则是这样的。
首先,弄出 N N 保证为偶数)张牌(当我没说扑克吧),每张牌上都有一个分数 Wi ,抽到这张牌的人将得到 Wi 的分数。
将这 N 张牌按照顺序叠成一叠。
两个人轮流抽牌,每次都只能抽现存的最上面的牌或者最下面的牌,并且不放回。
当牌堆被抽光的时候,分数最高的人胜利。
因为女士优先,每次都是阳姐先抽。
阳姐现在想知道,自己能不能赢,最多能得到多少分,自己得到最高分的时候会抽到原牌堆中的哪些牌。(当两种抽法得到的分数相等时,优先取最上面那张牌)
这样说可能会有些不敬,不过由于阳姐出色的(调)教(揉)练,小昊和大黄的智商可以视为极高,也就是说,双方都会执行对自己最有利的抽法。


输入

输入文件名为Poker.ni。
输入第一行一个正整数 N,代表牌堆中牌的个数。
第二行顺次包含 N 个数,代表牌堆中最上面的牌一直到最下面的牌的分数。


输出

输出文件名为Joker.ans。
输出第一行为“WIN”或“LOSE”,代表赢或者输。
输出第二行代表阳姐最高的得分。
输出第三行 N/2 个正整数,代表阳姐得到最高得分的时候,按她抽到的先后顺序,输出她抽到的牌在原来牌堆中的序号。


输入样例

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 j 的牌该怎样取最好(到底是那个人?看一下 ji 的奇偶性就行了!)。

fi,j=max(si,jfi+1,jwi,si,jfi,j1wj)

其中 si,j 等于第 i 张牌到第 j 张牌的得分和。


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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值