传送门:POJ 1837 Balance
分析:
g个挂钩挂上的极限值:15*25*20==7500。
那么在有负数的情况下是-7500~~7500 此时的平衡点为0。
我们当然可以将平衡点往右移7500个单位,范围就变成了 0~~15000。(正化方便处理,这样平衡点就是7500)
代码如下:
#include <stdio.h>
#include <string.h>
int dp[21][15001]; // dp[n][W]表示前n个砝码在W重量处出现的方案数量
int main(){
int i,j,k,C,G;
int pos[21],wight[21];
while(scanf("%d%d",&C,&G)!=EOF){
for(i=1;i<=C;i++)
scanf("%d",&pos[i]);
for(i=1;i<=G;i++)
scanf("%d",&wight[i]);
// init
memset(dp,0,sizeof(dp)); //每次记得初始化所有状态为0
dp[0][7500]=1; //两边不放砝码的平衡点方案为1
// 砝码是阶段 重量是状态
for(i=1;i<=G;i++) {
for(j=0;j<=15001;j++) {
for(k=1;k<=C;k++) {
if(j >= pos[k]*wight[i]) // 重量 = 臂长X臂力
// 选择第i砝码放亦或是不放两种决策
dp[i][j] += dp[i-1][j-pos[k]*wight[i]]; // 求有多少种方案 故 += 而不是 max
}
}
}
printf("%d\n",dp[G][7500]); //输出前G个砝码,达到平衡点7500的方案数
}
return 0;
}