TYVJ 1114 搭建双塔 解题报告
设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; }