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;
}
浙公网安备 33010602011771号