HDU ACM 4597 Play Game ->区间DP+记忆化搜索

分析:两个人都足够聪明,因此每个阶段都拿最大的。dp[sa][ea][sb][eb]分别表示区间1的开始为sa,结束为ea,区间2的开始为sb,结束为eb时能拿到的最大值。之后分别从四个方向上拿,是个搜索的过程。

[cpp]  view plain copy print ?
  1. #include<iostream>  
  2. using namespace std;  
  3.   
  4. int dp[25][25][25][25];  //dp[sa][ea][sb][eb],分别表示区间1的开始,结束,区间2的开始,结束  
  5. int a[25],b[25];  
  6.   
  7. int max(int a,int b)  
  8. {  
  9.     return a>b?a:b;  
  10. }  
  11.   
  12. int DFS(int sa,int ea,int sb,int eb,int sum) //两个人都很聪明,都尽量拿大的  
  13. {  
  14.     int ma;  
  15.     if(sa>ea && sb>eb)     //边界  
  16.         return 0;  
  17.     if(dp[sa][ea][sb][eb]>0)       //记忆化  
  18.         return dp[sa][ea][sb][eb];  
  19.   
  20.     ma=0;  
  21.     if(sa<=ea)  
  22.     {  
  23.         ma=max(ma,sum-DFS(sa+1,ea,sb,eb,sum-a[sa])); //取出区间1开始的值  
  24.         ma=max(ma,sum-DFS(sa,ea-1,sb,eb,sum-a[ea])); //取出区间1结尾的值  
  25.     }  
  26.     if(sb<=eb)  
  27.     {  
  28.         ma=max(ma,sum-DFS(sa,ea,sb+1,eb,sum-b[sb])); //取出区间2开始的值  
  29.         ma=max(ma,sum-DFS(sa,ea,sb,eb-1,sum-b[eb])); //取出区间2结尾的值  
  30.     }  
  31.   
  32.     dp[sa][ea][sb][eb]=ma;  
  33.     return ma;  
  34. }  
  35.   
  36. int main()  
  37. {  
  38.     int T,N,i,sum;  
  39.   
  40.     ios::sync_with_stdio(false);  
  41.     cin>>T;  
  42.     while(T--)  
  43.     {  
  44.         cin>>N;  
  45.         sum=0;  
  46.         for(i=1;i<=N;i++)  
  47.             sum+=(cin>>a[i],a[i]);  
  48.   
  49.         for(i=1;i<=N;i++)  
  50.             sum+=(cin>>b[i],b[i]);  
  51.         memset(dp,0,sizeof(dp));  
  52.         cout<<DFS(1,N,1,N,sum)<<endl;  
  53.     }  
  54.     return 0;  
  55. }

你可能感兴趣的:(编程,C++,c,算法,ACM)