区间DP

http://www.lightoj.com/volume_showproblem.php?problem=1031

 

给你n个数,A、B两个人从两端取数,每一次可以取连续的一段数,而且每个人都按让自己最优的方案去取数(即取的数的和尽可能大)

问最后A与B的差值最大是多少

解法:枚举区间长度,从小区间DP到大区间 

对于一段区间,枚举分隔点,要么取左边,要么取右边

下面是两种写法

View Code
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
const int inf = ~0u>>2;
int sum[110];
int dp[110][110];
inline int max(int a,int b){
    return a>b?a:b;
}
int main()
{
    int t,n,ca=1;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        sum[0]=0;
        memset(dp,0,sizeof(dp));
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&sum[i]);
            dp[i][i]=sum[i];
            sum[i]+=sum[i-1];
        }
        for(int len=1;len<n;len++)
        {
            for(int i=1;i+len<=n;i++)
            {
                dp[i][i+len]=sum[i+len]-sum[i-1];//必须先让dp数组有个初状态
                for(int j=i;j<i+len;j++)
                {
                       dp[i][i+len]=max(dp[i][i+len],sum[j]-sum[i-1]-dp[j+1][i+len]);
                       dp[i][i+len]=max(dp[i][i+len],sum[i+len]-sum[j]-dp[i][j]);
                }
            }
        }
        printf("Case %d: %d\n",ca++,dp[1][n]);
    }
    return 0;
}

 

View Code
#include<stdio.h>
#include<string.h>
const int inf = ~0u>>2;
int sum[110];
int dp[110][110];
inline int max(int a,int b){
    return a>b?a:b;
}
int DP(int l,int r){
    int &ret = dp[l][r];
    if(ret!=-inf) return ret;
    ret=sum[r]-sum[l-1];
    for(int m=l;m<r;m++){
        ret=max(ret,sum[m]-sum[l-1]-DP(m+1,r));
        ret=max(ret,sum[r]-sum[m]-DP(l,m));
    }
    return ret;
}
int main(){
    int t,n,ca=1;
    scanf("%d",&t);
    while(t--){
        scanf("%d",&n);
        sum[0]=0;
        for(int i=1;i<=n;i++)for(int j=i+1;j<=n;j++)        dp[i][j]=-inf;
        for(int i=1;i<=n;i++) {
            scanf("%d",&sum[i]);
            dp[i][i]=sum[i];
            sum[i]+=sum[i-1];
        }
        printf("Case %d: %d\n",ca++,DP(1,n));
    }
    return 0;
}
posted @ 2012-07-22 09:24  Because Of You  Views(691)  Comments(0Edit  收藏  举报