您的位置:首页 > 其它

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

2016-11-23 11:40 375 查看
题意:给你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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: