设f[i][j]是前i个水晶搭建成两座高度差值为j的较高的那座的高度,转移方程如下:
我用的不是f[i][j]=....,而是根据f[i][j]推出f[i+1][...],所以不好写方程,看代码吧:
#include <stdio.h>
#include <stdlib.h>
int num[101];
int f[101][200001];
#define max(a, b) ((a)>(b)?(a):(b))
int main(int argc, char **argv)
{
int i, j, sum = 0;
int n;
scanf("%d", &n);
for(i = 1; i <= n; i++){
scanf("%d", &num[i]);
sum += num[i];
}
for(i = 0; i <= n; i++){
for(j = 0; j <= sum; j++){
f[i][j] = -200000000;
}
}
f[0][0] = 0;
for(i = 0; i < n; i++){
for(j = 0; j <= sum; j++){
if(f[i][j] < 0){
continue;
}
f[i + 1][j] = max(f[i][j], f[i + 1][j]);
f[i + 1][j + num[i + 1]] = max(f[i + 1][j + num[i + 1]], f[i][j] + num[i + 1]);
if(j - num[i + 1] >= 0){
f[i + 1][j - num[i + 1]] = max(f[i + 1][j - num[i + 1]], f[i][j]);
}else{
f[i + 1][num[i + 1] - j] = max(f[i + 1][num[i + 1] - j], f[i][j] + num[i + 1] - j);
}
}
}
if(f[n][0] <= 0){
printf("Impossible\n");
return 0;
}
printf("%d\n", f[n][0]);
return 0;
}