POJ1837:Balance (分组背包+二维价格背包) By Assassin

题意:给你c(2<=c<=20)个挂钩,g(2<=g<=20)个砝码,求在将所有砝码(砝码重1~~25)挂到天平(天平长 -15~~15)上,并使得天平平衡的方法数

思路:(这个思路又不少我的,我真是垃圾…)因为有不同的挂钩的位置,每个挂钩上出现的数值最大为15*20*25=7500个,算上负数为-7500–7500,我们搬移一下到0-15000.

用二维数组dp[i][j]代表选择第i个砝码,状态值为j的情况下的解数(需要条件是当前状态j加上选择的i砝码的重量之后达到之前一个可达的状态,或者我们这么理解,这是一个倒着的状态,我们最后要求dp[m][7500]的状态数,我们将该点初始化可达,这里置dp[0][7500]1,然后每次通过运算可以到达已有意义状态点时说明dp[i][j]加上i砝码在某一位的生成值的时候可以到达dp[i-1][运算后值]有意义的点。)。

弱半天才懂,多看代码就明白了

#include<iostream>
#include<string.h>
#include<stdio.h> 
#define input freopen("input.txt","r",stdin)
using namespace std;
int dp[25][15500];
int ccc[30],ggg[30];
int main(){
    int c,g,i,j,k;
    while(scanf("%d%d",&c,&g)!=EOF){
        for(i=1;i<=c;i++){
            scanf("%d",&ccc[i]);
        }
        for(i=1;i<=g;i++){
            scanf("%d",&ggg[i]);
        }
        memset(dp,0,sizeof(dp));
        dp[0][7500]=1;
        for(i=1;i<=g;i++){
            for(j=15000;j>=0;j--){
                for(k=1;k<=c;k++){
                    if(j+ccc[k]*ggg[i]>=0&&j+ccc[k]*ggg[i]<=15000&&dp[i-1][j+ccc[k]*ggg[i]]){
                        dp[i][j]+=dp[i-1][j+ccc[k]*ggg[i]];
                    }
                }
            }
        }
        cout<<dp[g][7500]<<endl;
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值