标签:多少 lin problem cond scan -- eof input amp
【题意】有两堆东西,每个东西都有对应的值,每次拿都只能从上面或者底下拿,问先开始的那个人最多能拿到价值多少的东西。
【思路】数不是很大,开四维dp[l1][r1][l2][r2]表示在a堆还剩l1到r1和b堆还剩l2到r2能取得的最大值。
下面只要考虑从两堆的头尾取四种情况下,哪种的价值最多,sum-上一轮对方拿到的价值
#include<iostream> #include<algorithm> #include<string.h> using namespace std; const int N=25; int a[N],b[N]; int dp[N][N][N][N]; int dfs(int l1,int r1,int l2,int r2,int sum) { int mx=0; if(l1>r1&&l2>r2) return 0; if(dp[l1][r1][l2][r2]) return dp[l1][r1][l2][r2]; if(l1<=r1) { mx=max(mx,sum-dfs(l1+1, r1,l2, r2,sum-a[l1])); mx=max(mx,sum-dfs(l1,r1-1, l2, r2,sum-a[r1])); } if(l2<=r2) { mx=max(mx,sum-dfs(l1, r1,l2+1, r2,sum-b[l2])); mx=max(mx,sum-dfs(l1,r1, l2, r2-1,sum-b[r2])); } dp[l1][r1][l2][r2]=mx; return mx; } int main() { int t,n,sum; scanf("%d",&t); while(t--) { sum=0; scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d",&a[i]); sum+=a[i]; } for(int i=1;i<=n;i++) { scanf("%d",&b[i]); sum+=b[i]; } memset(dp, 0, sizeof(dp)); int ans=dfs(1,n,1,n,sum); cout<<ans<<endl; } return 0; }
标签:多少 lin problem cond scan -- eof input amp
原文地址:http://www.cnblogs.com/iwantstrong/p/6367543.html