• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

  • 联系
  • 订阅
  • 管理

View Post

母函数 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;
}

posted on 2010-09-22 11:41  sysuwhj  阅读(556)  评论(0)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3