POJ1837 Balance(01背包)
题意:给你c(2<=c<=20)个挂钩,g(2<=g<=20)个砝码,求在将所有砝码(砝码重1~~25)挂到天平(天平长 -15~~15)上,并使得天平平衡的方法数.......
思路:将g个挂钩挂上的极限值:15*25*20==7500
那么在有负数的情况下是-7500~~7500 以0为平衡点
那可以将平衡点往右移7500个单位,范围就是0~~15000
然后我们可以得出动态方程 dp[i][j+w[i]*c[k])+=dp[i-1][j];
故dp[g][7500]为天平平衡的情况
#include <iostream> #include <cstring> using namespace std; int n,m; int l[21],w[21]; int dp[21][15000]; int main() { ios::sync_with_stdio(false); cin>>n>>m; for(int i=1;i<=n;i++) cin>>l[i]; for(int i=1;i<=m;i++) cin>>w[i]; memset(dp,0,sizeof(dp)); dp[0][7500]=1;// 0对应7500,挂上前0个钩码后,天枰达到平衡状态7500的方法有1个,就是两端都不挂 for(int i=1;i<=m;i++) { for(int j=0;j<15000;j++) { if(dp[i-1][j])// 当放入i-1个钩码时状态j已经出现且被统计过方法数,则直接使用统计结果,否则忽略当前状态j { for(int k=1;k<=n;k++) { dp[i][j+l[k]*w[i]]+=dp[i-1][j]; } } } } cout<<dp[m][7500]<<endl;// return 0; }