loj 1031(区间dp+记忆化搜索)
题目链接:http://lightoj.com/volume_showproblem.php?problem=1031
思路:dp[i][j]表示从区间i-j中能取得的最大值,然后就是枚举分割点了。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 #define inf 1<<30 7 #define FILL(a,b) memset(a,b,sizeof(a)) 8 9 int dp[111][111],sum[111]; 10 int n,x; 11 12 int dfs(int l,int r) 13 { 14 if(dp[l][r]!=-inf)return dp[l][r]; 15 int ans=sum[r]-sum[l-1]; 16 for(int k=l;k<=r;k++){ 17 ans=max(ans,sum[k]-sum[l-1]-dfs(k+1,r));//取左边的 18 ans=max(ans,sum[r]-sum[k-1]-dfs(l,k-1));//取右边的 19 } 20 return dp[l][r]=ans; 21 } 22 23 24 int main() 25 { 26 int _case,t=1; 27 scanf("%d",&_case); 28 while(_case--){ 29 scanf("%d",&n); 30 FILL(sum,0); 31 for(int i=0;i<=n;i++) 32 for(int j=0;j<=n;j++)dp[i][j]=-inf; 33 for(int i=1;i<=n;i++){ 34 scanf("%d",&x); 35 dp[i][i]=x; 36 sum[i]=sum[i-1]+x; 37 } 38 printf("Case %d: %d\n",t++,dfs(1,n)); 39 } 40 return 0; 41 }