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

 

你可能感兴趣的:(dp)