【poj1837】Balance
这个题我们可以把它转化成01背包,因为阻力臂*阻力=动力臂*动力(初中物理),所以说要使两方平衡,二者绝对值要保持一致。所以说可能会出现负数,那么我们将所有的数统一加上一个值,因为-15<=c[i]<=15, w[i]<=25,g<=20,所以绝对值最大为15*25*20=7500,因此统一加上7500,就可以转化成01背包了
#include<iostream> #include<cstring> #include<cstdio> #include<cmath> using namespace std; int c,g,c1[25],w[25],t,dp[2][15010]; int main() { scanf("%d%d",&c,&g); for(int i=1;i<=c;i++) scanf("%d",&c1[i]); for(int i=1;i<=g;i++) scanf("%d",&w[i]); dp[0][7500]=1; for(int i=1;i<=g;i++)//一定要先枚举物品,因为多个物品可以对应一个挂钩 { t=1-t;//滚动数组优化 for(int j=0;j<=15000;j++) dp[t][j]=0; for(int j=0;j<=15000;j++) { if(dp[1-t][j])//如果上一次选取物品的时候得到平衡度为j的时候 { for(int k=1;k<=c;k++)//再去进行转移 dp[t][j+c1[k]*w[i]]+=dp[1-t][j]; } } } printf("%d",dp[t][7500]);//默认设置平衡时,平衡度为7500 }