DP还是菜啊。。开始题意就没理解对,以为所有的材料都要用上,天真地用01背包做了,高度为总和的一半,果断WA。。后来翻看大神的题解,发现材料不必全部用完,只要能够组成相同高度的双塔,并输出最高的高度就行。。题解是用高度差为下标,低塔高度为值进行DP,每次状态转移有3种情况,把新材料放在低塔上,放在高塔上,不放进去,分别推最优解就行。。代码大部分参考自别人的,空间可以优化,别人用的滚动数组,我这边没有优化,感觉抄袭太多了已经,唉,接下来一定要自己好好思考啊
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
static int min(int a, int b)
{
return a < b ? a : b;
}
static int max(int a, int b)
{
return a > b ? a : b;
}
int main()
{
int n, dp[100][2001];
while (scanf("%d", &n), n >= 0)
{
memset(dp[0], -1, sizeof(dp[0]));
dp[0][0] = 0;
int num, i, k, d, new;
for (k = 1; k <= n; k++)
{
scanf("%d", &num);
memset(dp[k], -1, sizeof(dp[k]));
for (i = 0; i <= 2000; i++)
if (dp[k - 1][i] != -1)
{
d = abs(num - i);
new = min(dp[k - 1][i] + num, dp[k - 1][i] + i);
dp[k][d] = max(dp[k][d], new);
d = num + i;
if (d <= 2000)
dp[k][d] = max(dp[k][d], dp[k - 1][i]);
dp[k][i] = max(dp[k][i], dp[k - 1][i]);
}
}
if (dp[n][0] == 0 || dp[n][0] == -1)
puts("Sorry");
else
printf("%d\n", dp[n][0]);
}
return 0;
}