POJ 1837 Balance 0-1背包

来源:互联网 发布:backtrack5软件下载 编辑:程序博客网 时间:2024/06/05 13:06

背包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;}

 

原创粉丝点击