描述
厦门大学最近很流行一种游戏:将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;
}