题目大意:          要你输入n,代表学院里面有n种设备,并且在下面输入n行,每一行输入v,m代表设备的价格为v,设备的数量是m.然后要求把这些设备的总价值分摊,尽量平分,使其总价值接近相等,最好是相等。 解题思路:          一开始有点儿难转换为母函数,好像很多牛人都用DP做嘞,速度上应该更快吧。转换为母函数的思路是:把设备排列组合,把所有可能的组合都打出来,然后从总价值的中间开始搜,只要搜到第一个就是了,再用total-i就是最靠近的两个价值了。。所以输出是total-i,i。这就不用担心总价值是奇数了。写出母函数的生成函数就可以快速秒掉了。母函数用了1500MS,这样算慢吧。应该比DP要慢很多,但是题目给了5000MS的上限,哈~母函数还是挺伟大滴。 代码:
#include
#include
using namespace std;
const int MAX=55;
const int AMAX=250005;
typedef struct f
{
	int val;
	int c;
	int sum;
}F;
int c1[AMAX],c2[AMAX];
int main(void)
{
	F fa[MAX];
	int n,i,j,k;
	while(cin>>n)
	{
		if(n<0)
			exit(0);
		int tal=0;
		memset(c1,0,sizeof(c1));
		memset(c2,0,sizeof(c2));
		for(i=1;i<=n;i++)
		{
			cin>>fa[i].val>>fa[i].c;
			fa[i].sum=fa[i].val*fa[i].c;
			tal+=fa[i].sum;
		}
		c1[0]=1;
		for(i=fa[1].val;i<=fa[1].sum;i+=fa[1].val)
			c1[i]=1;

		for(i=2;i<=n;i++)
		{
			for(j=0;j<=tal;j++)
			{
				for(k=0 ; k+j<=tal && k<=fa[i].sum ; k+=fa[i].val)
				{
					c2[k+j]+=c1[j];
				}
			}
			for(j=0;j<=tal;j++)
			{
				c1[j]=c2[j];
				c2[j]=0;
			}
		}

	//	cout<=0;i--)//从中间开始搜,用tal-i,不用担心tal为奇数
		{
			if(c1[i]!=0)
			{
				cout<
 
posted on 2011-11-02 22:13  cchun  阅读(319)  评论(0编辑  收藏  举报