Poj 1837 Balance(经典分组背包)

题目大意:

有一个天平,天平左右两边各有若干个钩子,总共有C个钩子,有G个钩码,求将钩码全部挂到钩子上使天平平衡的方法的总数。

其中可以把天枰看做一个以x轴0点作为平衡点的横轴

看了会儿,发现不会,于是看了看http://blog.csdn.net/zhuyongqingacm/article/details/8882245,于是参考了看了一遍

dp[i][j] 意味:放上第 i 个钩码,平衡状态为 j 的种类,这里 j==7500就是平衡状态

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int dp[21][15001];
int main()
{
	int C,G,c[25],g[25];   // 挂钩数量,钩码数量
	while(cin >> C >> G )
	{
		int i,j,k;
		for( i = 1 ; i <= C ;i ++)
		{
			cin >> c[i];
		}
		for( i = 1 ; i <= G ;i++)
			cin >> g[i];
		memset(dp,0,sizeof(dp));
		dp[0][7500] = 1;   // 7500 是平衡状态,当一个挂钩都不放的时候刚好有一种平衡
		for( i = 1 ;i <= G ;i ++)             // 挂每一个钩码
		{
			for( j = 0 ;j <= 15000 ;j ++)     //将钩码 i 挂到每一个位置
			{
					if(dp[i - 1][j])          //如果上一个状态合法
					{
						for(k = 1 ;k <= C ;k ++)   // 每一个钩码都被当做 钩码 i 挂上去
							dp[i][j + g[i] * c[k]] += dp[i -1][j];  // 在挂第 i 个钩码时,每一个挂钩的位置都去放一下每一个每一个钩码
																	//	挂上钩码 i 后,那么就相当于放第i个钩码时平衡度为 j + g[i] * c[k] 的种类增加了dp[i -1][j]种
					}
			}
		}
		cout << dp[G][7500] << endl;
	}
	return 0;
}


你可能感兴趣的:(Poj 1837 Balance(经典分组背包))