XMU算法上机:纸片选择

该文描述了一个在厦门大学流行的两人游戏,玩家轮流从两端取包含价值的纸片,目标是最大化自己的总价值。文章通过递归算法探讨了先手玩家在最坏情况下的最优策略,以确保至少能获得一定的价值。
摘要由CSDN通过智能技术生成

描述

厦门大学最近很流行一种游戏:将2n张纸片依次进行排序,每张纸片上都写着一个价值a[i]。双方进行轮流操作,每次操作可以从首部或尾部拿走一张纸片并获得纸片上的价值,纸片不再放回,纸片取完后获得价值多的一方获胜。现在你是先手,你很明白你的对手足够聪明,请问你在最坏情况下最多可以获得多少的价值。

出题者:秦豪远同学

输入

第一行包含一个整数n(n<=6)

接下来一行,一共2n个数字,代表每张纸片上的价值a[i](0<=a[i]<=100)

输出

输出一个整数,代表你最多可以获得的价值。

输入样例 1

3

4 3 8 9 1 5

输出样例 1

17

思路主要是递归。

最后我方的得分用变量Ms表示。

主函数就是输入数据,然后把数组传给getscore。

在getscore函数中,定义四个输入量,数组,头,尾,以及一个判断值(用于判断是我方回合还是敌方回合,在递归操作中只要进行取反就行)

以下是代码部分:

#include "iostream"
using namespace std;
int Ms=0;
void getscore(int *a,int p1,int p2,bool tag){
    if(p2==p1)return;
    else if(p2-p1<=2){//剩3个数的时候已经不用考虑,选首尾中最大的一个就行
        if(tag)Ms+=max(a[p1],a[p2]);
        if(a[p1]>a[p2])p1++;
        else p2--;
        getscore(a,p1,p2,!tag);
        return;
    }
    int num=Ms,num1=0,num2=0;//存下Ms当前值,便于后续操作恢复
    if(tag){
        num1+=a[p1];
        num2+=a[p2];
    }
    Ms=0;//清零Ms,用于后续比较
    getscore(a,p1+1,p2,!tag);
    num1+=Ms;
    Ms=0;//再次清零
    getscore(a,p1,p2-1,!tag);
    num2+=Ms;
    if(tag)Ms=max(num1,num2)+num;//我方回合要达到最大
    else Ms=min(num1,num2)+num;//敌方回合要使得我方最小
    return;
}
int main(){
    int n;
    cin>>n;
    int a[2*n];
    for (int i = 0; i < 2 * n; ++i) {
        cin>>a[i];
    }
    getscore(a,0,2*n-1, true);
    cout<<Ms;
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值