Vijos P1037 搭建双塔(动态规划)

分析:dp[i][j]表示前I个数字高度差为J的高塔的高度、于是YY出转移方程

#include
#include
#include
using namespace std;
int n;
int dp[105][20005];
int num[105];
int main()
{
    scanf("%d",&n);
    int sum=0;
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&num[i]);
        sum+=num[i];
    }
    memset(dp,-1,sizeof(dp));
    dp[0][0]=0;
    int a;
    for(int i=1;i<=n;i++)
    {
        for(int j=0;j<=sum;j++)
        {
            if(dp[i-1][j]>-1)
                dp[i][j]=dp[i-1][j];
            if(num[i]>j&&dp[i-1][num[i]-j]>-1)
                dp[i][j]=max(dp[i][j],dp[i-1][num[i]-j]+j);
            if(j+num[i]<=sum&&dp[i-1][j+num[i]]>-1)
                dp[i][j]=max(dp[i][j],dp[i-1][j+num[i]]);
            if(j>=num[i]&&dp[i-1][j-num[i]]>-1)
                dp[i][j]=max(dp[i][j],dp[i-1][j-num[i]]+num[i]);
        }
    }
    if(dp[n][0]>0)
        printf("%d\n",dp[n][0]);
    else printf("Impossible\n");
    return 0;
}



你可能感兴趣的:(ACM竞赛)