CF某gym H

题目大意:给定n个数(n<=1000),A和B玩取数游戏,每次只能取两端中的一个数,两个人都希望自己和对方的分差越大越好

A先手,永远按照最优策略来,B比较呆,所以一直取最大的,问A最优情况下能比B多得几分

做法:显然这种题都是dp题,我们用dp[l][r]表示区间[l,r]都取完的情况下A能比B多得几分

显然转移比较困难,所以我们考虑用记忆化搜索

枚举每次取哪边,然后转移一下就好了,复杂度显然是n^2的

代码:

#include<bits/stdc++.h>
#define N 1005
using namespace std;
int dp[N][N],a[N],n;
int dfs(int l,int r){
	if (dp[l][r]) return dp[l][r];
	if (l+1==r) return abs(a[r]-a[l]);
	int tmp1=-1e9,tmp2=-1e9;
	if (a[l+1]<a[r]) tmp1=a[l]-a[r]+dfs(l+1,r-1);
	else tmp1=a[l]-a[l+1]+dfs(l+2,r);
	if (a[l]>=a[r-1]) tmp2=a[r]-a[l]+dfs(l+1,r-1);
	else tmp2=a[r]-a[r-1]+dfs(l,r-2);
	return dp[l][r]=max(tmp1,tmp2);
}
int main(){
	int cas=0;
	while (scanf("%d",&n)!=EOF){
		if (n==0) return 0;
		cas++;
		memset(dp,0,sizeof(dp));
		for (int i=1;i<=n;i++) scanf("%d",&a[i]);
		int ans1=dfs(1,n);
		//printf("%d\n",ans1);
		printf("In game %d, the greedy strategy might lose by as many as %d points.\n",cas,ans1);
	}
	return 0;
}

  

posted @ 2018-05-04 08:43  longint  阅读(108)  评论(0编辑  收藏  举报