POJ 1837 C - Balance(01背包)(dp)

来源:互联网 发布:什么比价软件好 编辑:程序博客网 时间:2024/05/21 10:28

这道题又是一道简单典型的背包问题,然而并不是很好想到怎么写;

这种老题目相比较cf题意有点晦涩~orz

主要讲的是给你一个天平,天平的两边一共有C个挂钩,再给你G个重量不同的物体,要求把物体全挂在两边的钩子上,要使天平平衡,问有多少种方案。挂的时候是用距离*重量来计算平衡,由于给的物体重量和个数都比较小,就可以用01背包来解决,遍历G个物体,考虑该物体是否挂在第Ci个钩子上,当重量为0的时候即为平衡。但是重量为负数的时候不好用数组存,就都加最大范围的重量,即7500 = 15(钩子距离)*25(重量范围)*20(物体的个数);

设dp[i][j],i表示物体i,j表示天平加上当前物体*距离的重量,dp[i][j]的值表示方案数,初始化dp[0][7500] = 1,表示什么都不放有一种方案。最后只要输出dp[G][7500],即为G个物体全放完、且保持平衡的方案数。


#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;int c[25],w[25],dp[25][15005]; //dp存方案数int main() {int n,m;scanf("%d%d",&n,&m);for(int i = 1;i <= n;i++)scanf("%d",&c[i]);for(int i = 1;i <= m;i++)scanf("%d",&w[i]);memset(dp,0,sizeof(dp)); //初始化每个状态方案数为0dp[0][7500] = 1; //什么都不放有一种方案for(int i = 1;i <= m;i++)for(int j = 0;j <= 15000;j++)if(dp[i-1][j])  //如果重量为j的时候存在方案,就加进算上w[i]*c[k]后的方案数内for(int k = 1;k <= n;k++)dp[i][j + w[i]*c[k]] += dp[i-1][j];printf("%d\n",dp[m][7500]);}


0 0
原创粉丝点击