母函数 HDU 1709 The Balance

这题大概意思是,给你n个砝码和一个天平,叫你找出从1 到 这n个砝码总和的范围内,找出不能称出的重量

可以套用母函数模板, 多项式相乘时,多了负指数。注意这题只是存在性,不需要求出每种重量的组合数,

直接标记就可以了。

还有一点需要注意,乘出来的多项式,负指数和正指数是相互对称的,只存其中一边即可

#include<iostream>

#include <math.h>

using namespace std;





int main()

{

	int a[10010];

	int positive[10010];

	int negative[10010];

	int num[120];

	int n;

	int hold;

	int maxindex;

	int firstboundary, secondboundary;

	int addnum;

	int counter;



	//freopen("C:\\Users\\Haojian\\Desktop\\test.txt", "r", stdin);



	while (cin >> n)

	{

		//数据初始化

		counter = 0;

		maxindex = 0;

		firstboundary = 0;



		for (int i = 0; i < 10010; i++)

		{

			a[i] = 0;

			positive[i] = 0;

			negative[i] = 0;

		}



		cin >> hold;

		negative[hold] = 1;

		negative[0] = 1;

		num[0] = hold;

		maxindex = hold;

		positive[hold] = 1;

		positive[0] = 1;



		for (int i = 1; i < n; i++)

		{

			cin >> hold;

			num[i] = hold;			

			maxindex += hold;

		}



		//类似母函数模板

		for (int i = 2; i <= n; i++)

		{

			//求2个上界

			firstboundary = 0;

			for (int k = i - 2; k >= 0; k--)

				firstboundary += num[k];

			

			secondboundary = firstboundary + num[i - 1];

			addnum = num[i-1];//当前乘的第i个多项式的每个项的指数每次增加的次数

			

			for (int j = -firstboundary; j <= firstboundary; j++)//从负数开始计算

			{

				if (negative[abs(j)])//negative数组是标记数组,记录目前求出的多项式是否有指数为j的项, 其下标是多项式项的指数

				

				for (int k = -addnum; k + j <= secondboundary && k <= num[i - 1]; k += addnum)//乘以下一个多项式

					if (k +	j >= 0 )

					{

						positive[k+j] = 1;//记录可以称量的数目,positive数组下标是可以称量的数量

						a[k+j] = 1;

					}

					else

					   a[-(k+j)] = 1;//记录乘出来的负指数的项					

			}



			//修改negative标记数组,重置a

			for (int j = 0; j <= secondboundary; j++)

			{

				negative[j] = a[j];

				a[j] = 0;

			}

			

			

		}

		

		//输出

		for (int i = 0; i <= maxindex; i++)

		{

			if (positive[i] == 0)

				counter++;

		}

		

		cout << counter << endl;

		if (counter != 0)

		{	

			for (int i = 1; i <= maxindex; i++)

			{

				if (positive[i] == 0 && counter > 1)

				{

					cout << i << " ";

					counter--;

				}

				else



					if (positive[i] == 0 && counter == 1)

					{

						cout << i;

						break;

					}

			}

				cout << endl;

		}

	}



	return 0;

}



你可能感兴趣的:(HDU)