http://poj.org/problem?id=1837
(1)用dp[i][j]表示挂了 i 个重物时 平衡度为 j 的数目;
(2)核心部分:
for(j=1;j<=m;j++) for(k=0;k<=15000;k++) if(dp[j-1][k]) for(i=1;i<=n;i++) dp[j][k+c[i]*g[j]]+=dp[j-1][k];
其中, j 表示重物编号, k 是背包, i 为所挂位置。注意循环的顺序,先确定重物,再打开背包,最后逐个转移平衡度。
(3)由于力矩的变化才是本题的关键,将中间位置设为平衡位置(dp[0][7500]=1;),力矩为7500时即为平衡。
具体代码:


#include<stdio.h> #include<string.h> int n, m; int g[21], c[21]; int dp[21][15001]; int main() { int i, j, k; while(scanf("%d%d", &n, &m)!=EOF) { for(i=1;i<=n;i++) scanf("%d", &c[i]); for(j=1;j<=m;j++) scanf("%d", &g[j]); memset(dp, 0, sizeof(dp)); dp[0][7500]=1; for(j=1;j<=m;j++) for(k=0;k<=15000;k++) if(dp[j-1][k]) for(i=1;i<=n;i++) dp[j][k+c[i]*g[j]]+=dp[j-1][k]; printf("%d\n", dp[m][7500]); } }