hdu 4597

题意:alice和bob,2个数列,他们只能从A/B数列的最左/右取数字,问alice最多取多少,alice先取

思路:dp[i][j][k][l]表示A数列剩下i---j,B数列剩下k--l,当前这个人取得的最大值,

      总和-min(dp[2][r][1][r],dp[1][r-1][1][r],dp[1][r][2][r],dp[1][r][1][r-1])即alice取的最大值,里面的即bob取得的最大值,但是我们得从里面选个最小的

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int N=25;
 4 
 5 int dp[N][N][N][N];
 6 int a[N],b[N];
 7 
 8 int hh(int l1,int r1,int l2,int r2){
 9     if(dp[l1][r1][l2][r2]!=-1) return dp[l1][r1][l2][r2];
10     if(l1>r1) dp[l1][r1][l2][r2]=0;
11     if(l2>r2) dp[l1][r1][l2][r2]=0;
12     int sum=0,ans=0;
13     if(l1<=r1) sum+=a[r1]-a[l1-1];
14     if(l2<=r2) sum+=b[r2]-b[l2-1];
15     if(l1<=r1){
16         ans=max(ans,sum-hh(l1+1,r1,l2,r2));
17         ans=max(ans,sum-hh(l1,r1-1,l2,r2));
18 
19     }
20     if(l2<=r2){
21         ans=max(ans,sum-hh(l1,r1,l2+1,r2));
22         ans=max(ans,sum-hh(l1,r1,l2,r2-1));
23     }
24     return dp[l1][r1][l2][r2]=ans;
25 }
26 
27 int main(){
28     int t;
29     scanf("%d",&t);
30     while(t--){
31         int n;
32         scanf("%d",&n);
33         int x;
34         memset(a,0,sizeof(a));
35         memset(b,0,sizeof(b));
36         memset(dp,-1,sizeof(dp));
37         for(int i=1;i<=n;i++){
38             scanf("%d",&x);
39             a[i]=a[i-1]+x;
40         }
41         for(int i=1;i<=n;i++){
42             scanf("%d",&x);
43             b[i]=b[i-1]+x;
44         }
45         cout<<hh(1,n,1,n)<<endl;
46     }
47     return 0;
48 }
原文地址:https://www.cnblogs.com/hhxj/p/7243119.html