纸片选择
题目描述
题目分析
解决方案
题目描述
厦门大学最近很流行一种游戏:将2n张纸片依次进行排序,每张纸片上都写着一个价值a[i]。双方进行轮流操作,每次操作可以从首部或尾部拿走一张纸片并获得纸片上的价值,纸片不再放回,纸片取完后获得价值多的一方获胜。现在你是先手,你很明白你的对手足够聪明,请问你在最坏情况下最多可以获得多少的价值。
出题者:秦豪远同学
输入
第一行包含一个整数n(n<=6)
接下来一行,一共2n个数字,代表每张纸片上的价值a[i](0<=a[i]<=100)
输出
输出一个整数,代表你最多可以获得的价值。
输入样例:
3
4 3 8 9 1 5
输出样例:
17
题目分析:
思路:该问题需要考虑全局的变化情况,这里选择递归算法choose(int num[],int len),返回值即是每个num[]所求最大值。
(1)函数每次传递的参数是剩下的牌组成的数组及其牌数,每一轮递归两人各完成一次选择。
(2)递归出口是剩下两张牌,返回较大的数值即可
(2)对于给定的2n张牌,自己优先选择有两种情况:choose->L和choose->R,表示自己选择完之后能从剩下的牌中获得的最大值。然后对手选择再分两种情况,一共就有四种情况,分别是①choose->L->L、②choose->L->R、③choose->R->L、④choose->R->R,表示一轮选择之后自己能从剩下的牌中获得的最大值。按照题目要求,需要在自己选牌的时候考虑最好情况,对方选牌考虑最坏的情况。例如自己的选择choose->L,那么共有①和②两种情况,由于是对手选择后产生的,所以考虑最坏情况,即choose->L=min(choose->L->L,choose->L->R)。若是choose->R,有③和④,同理考虑最坏情况,即choose->R=min(choose->R->L,choose->R->R)。这样就剩下两种情况,由于这两种情况是自己选择产生的,于是考虑最好情况,choose=max(choose->L+num[L],choose->R+num[R]),即是以下程序中的:
max(
num[0] + min( choose(num+2,len-2) , choose(num+1,len-2) ),
num[len-1] + min( choose(num,len-2) , choose(num+1,len-2) )
)
解决方案:
#include <iostream>
using namespace std;
int choose(int num[],int len){
if(len==2)
return max(num[0],num[1]);
return max(num[0]+min(choose(num+2,len-2),choose(num+1,len-2)),num[len-1]+min(choose(num,len-2),choose(num+1,len-2)));
}
int main(){
int n;
cin>>n;
int num[2*n];
for(int i=0;i<2*n;i++)
cin>>num[i];
cout<<choose(num,2*n);
return 0;
}