HDU4597:Play Game(记忆化搜索(dp))(博弈)

来源:互联网 发布:安徽移动网络速度慢 编辑:程序博客网 时间:2024/05/22 13:37

Alice and Bob are playing a game. There are two piles of cards. There are N cards in each pile, and each card has a score. They take turns to pick up the top or bottom card from either pile, and the score of the card will be added to his total score. Alice and Bob are both clever enough, and will pick up cards to get as many scores as possible. Do you know how many scores can Alice get if he picks up first?
Input
The first line contains an integer T (T≤100), indicating the number of cases.
Each case contains 3 lines. The first line is the N (N≤20). The second line contains N integer a i (1≤a i≤10000). The third line contains N integer b i (1≤b i≤10000).
Output
For each case, output an integer, indicating the most score Alice can get.
Sample Input
2

1
23
53

3
10 100 20
2 4 3
Sample Output
53
105

题意
Alice和Bob玩一个游戏,有两个长度为N的正整数数字序列,每次他们两个
只能从其中一个序列,选择两端中的一个拿走。他们都希望可以拿到尽量大
的数字之和,并且他们都足够聪明,每次都选择最优策略。Alice先选择,问
最终Alice拿到的数字总和是多少?

题解:用dp[i][j][p][q]表示只能从a串的i位到j位,b串的p位到q位拿(其他位置此时当作没有数,不考虑),此时都拿完后先手的数之和最大为dp[i][j][p][q],则因为下一步必为后手拿,所以答案为sum(i,j,p,q)-min{ dp[所有当前状态的后继状态](如dp[i+1][j][p][q],dp[i][j-1][p][q]。。。) }(这是为了让下一步对手为先手时拿到的尽量小)。在计算时,可以用记忆话搜索解决。

#include <cstdio>#include <iostream>#include <algorithm>#include <cstring>using namespace std;const int maxn = 20 + 5;int dp[maxn][maxn][maxn][maxn];int a[maxn],b[maxn];int suma[maxn],sumb[maxn];int sumam,sumbm,sum;int n;int get_sum(int a,int b,int c,int d){    return suma[b]-suma[a-1]+sumb[d]-sumb[c-1];}int dfs(int i,int j,int p,int q){    if(dp[i][j][p][q]!=-1) return dp[i][j][p][q];    dp[i][j][p][q]=0;    if(i<=j) dp[i][j][p][q]=max(dp[i][j][p][q],get_sum(i,j,p,q) - dfs(i+1,j,p,q));    if(i<=j) dp[i][j][p][q]=max(dp[i][j][p][q],get_sum(i,j,p,q) - dfs(i,j-1,p,q));    if(p<=q) dp[i][j][p][q]=max(dp[i][j][p][q],get_sum(i,j,p,q) - dfs(i,j,p+1,q));    if(p<=q) dp[i][j][p][q]=max(dp[i][j][p][q],get_sum(i,j,p,q) - dfs(i,j,p,q-1));    return dp[i][j][p][q];}int main(){    freopen("D.in","r",stdin);    freopen("D.out","w",stdout);    int kase;scanf("%d",&kase);    while(kase--){        memset(dp,-1,sizeof(dp));        for(int i=1;i<=n;i++)             for(int j=1;j<=n;j++)                 dp[i][i-1][j][j-1]=0;        scanf("%d",&n);        for(int i=1;i<=n;i++)  {            scanf("%d",&a[i]);            suma[i]=suma[i-1]+a[i];        }        for(int i=1;i<=n;i++)  {            scanf("%d",&b[i]);            sumb[i]=sumb[i-1]+b[i];        }        sum = suma[n]+sumb[n];        dfs(1,n,1,n);        printf("%d\n",dp[1][n][1][n]);    }    return 0;}
0 0
原创粉丝点击