蓝桥杯 算法训练 逗志芃的危机
 
题目描述
 
- 资源限制
 时间限制:1.0s 内存限制:256.0MB
- 问题描述
 逗志芃又一次面临了危机。逗志芃的妹子是个聪明绝顶的人,相比之下逗志芃就很菜了。现在她妹子要和他玩一个游戏,这个游戏是这样的:一共有n个数(n是偶数)写成一行,然后两个人轮流取数,每次只能从最前面或者最后面取走一个数,全部取完则游戏结束,之后每个人取走的数的和就是每个人的得分。由于逗志芃妹子很厉害,但他又不想输,所以只能找到你了,你要告诉他最多可以得到多少分。(注意,妹子智商是maxlongint所以是不会犯错的,每次的策略必然最优,而且逗志芃是先手)
- 输入格式
 第一行一个数n,表示有n个数。
 第二行就是进行游戏的n个数。
- 输出格式
 一个数,最高得分
- 样例输入
 2
 10 20
- 样例输出
 20
- 数据规模和约定
 例:0<n,m<=1000,每个数不超过10000 。
方案1 递归 记忆化搜索 剪枝 博弈论
 
#include<iostream>
#include<algorithm>
using namespace std;
int n;					
int	nums[1000];			
int ans[1000][1000];	
int f(int L, int R, int nums[], int id){
	
	if(ans[L][R]!=0){
		return ans[L][R];
	}
	
	
	if(L==R){
		return 0;
	}
	
	
	if(id==0){
		return ans[L][R] = max(nums[L]+f(L+1, R, nums, 1), nums[R]+f(L, R-1, nums, 1));
	}else{	
		return ans[L][R] = min(f(L+1, R, nums, 0), f(L, R-1, nums, 0));
	}
}
					
int main(){	
	cin>>n;
	for(int i=0; i<n; ++i){
		cin>>nums[i];
	}
	cout<<f(0, n-1, nums, 0)<<endl;
	return 0; 
} 
 
方案2 动态规划 博弈论
 
#include<iostream>
#include<algorithm>
using namespace std;
int n;					
int	nums[1000];			
int ans[1000][1000];	
					
int main(){	
	cin>>n;
	for(int i=0; i<n; ++i){
		cin>>nums[i];
	}
	
	for(int R=0; R<n; ++R){
		for(int L=R; L>=0; --L){
			
			if(L == R){
				ans[L][R] = 0;
			}else if((R-L)&1){	
				ans[L][R] = max(nums[L]+ans[L+1][R], nums[R]+ans[L][R-1]);
			}else{				
				ans[L][R] = min(ans[L+1][R], ans[L][R-1]); 
			}
		}
	} 
	
	cout<<ans[0][n-1]<<endl;
	return 0; 
}