POJ 1837 Balance 0-1背包
背包DP
题意:有一杆秤,秤上有c个挂钩(2<=c<=20)(在左为负,在右为正,范围-15—15),另有g(2<=g<=20)个砝码(质量各不相同,范围1-25),要 求把所有砝码挂到挂钩上能使秤平衡的种数。
分析:每个砝码必须放在c个挂钩上的其中一个。
用数组dp[i][j](j表示一个状态,力矩+7500)表示放完第i个砝码后,各个状态存在的种数;
确定数组范围:显然0<=i<=20,而对于j,取最极端的数据, 挂钩在15位置,g=20,质量都为25,则计算得力矩最大值15*25*20=7500;挂钩在-15时,同理得力矩最大值-7500;为了避免出现负数,j为力矩+7500;
初始化:平衡点,没有砝码,dp[0][7500]=1;
状态转移方程:
if(dp[i-1][j])dp[i][j+a[k]*b[i]]+=dp[i-1][j]; (1<=k<=c)
AC代码:
View Code
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; int dp[23][15003]; int a[23],b[23]; int main() { int c, g, i, j ,k; while(~scanf("%d%d",&c,&g)) { memset(dp,0,sizeof(dp)); for(i=1;i<=c;i++) scanf("%d",&a[i]); for(i=1;i<=g;i++) scanf("%d",&b[i]); dp[0][7500]=1; for(i=1;i<=g;i++) { for(j=0;j<=15000;j++) if(dp[i-1][j]) for(k=1;k<=c;k++) dp[i][j+a[k]*b[i]]+=dp[i-1][j]; } printf("%d\n",dp[g][7500]); } return 0; }


浙公网安备 33010602011771号