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; }