loj 1031(区间dp+记忆化搜索)

题目链接:http://lightoj.com/volume_showproblem.php?problem=1031

思路:dp[i][j]表示从区间i-j中能取得的最大值,然后就是枚举分割点了。

 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 }
View Code

 

posted @ 2013-10-06 15:40  ihge2k  阅读(299)  评论(0编辑  收藏  举报