首页 > 其他 > 详细

luogu P1450 [HAOI2008]硬币购物

时间:2020-06-06 09:07:04      阅读:39      评论:0      收藏:0      [点我收藏+]

应该算是我做的正儿八经的容斥的第一道题吧。

直接做时间复杂度是\(O(4nS)\)的,显然不能接受。注意到这题只有\(4\)个物品,考虑容斥。

容斥模型

  • 元素:每一种方案
  • 全集:所有组合总和为\(n\)的方案
  • 属性:对每个物品购买的数量限制

这道题显然是对每个属性求交集,于是转化成了全集-补集的并集模型,由于只有\(4\)个物品,所以可以直接预处理+暴力枚举,时间复杂度\(O(4max(S),2^4n)\)

代码:

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>

using namespace std;

typedef long long LL;
const int N=100000;
int c[5],n,d[5],s;
LL f[N+9];

void init()
{
	for (int i=1;i<=4;i++)
		scanf("%d",&c[i]);
	scanf("%d",&n);
	f[0]=1;
	for (int i=1;i<=4;i++)
		for (int j=c[i];j<=N;j++)
			f[j]+=f[j-c[i]];
}

void work()
{
	while(n--)
	{
		for (int i=1;i<=4;i++)
			scanf("%d",&d[i]);
		scanf("%d",&s);
		LL ans=0;
		for (int i=1;i<16;i++)
		{
			int cnt=0;LL m=s;
			for (int j=1;j<=4;j++)
				if(i&(1<<j-1))
					cnt++,m-=1ll*(d[j]+1)*c[j];
			if(m>=0) ans+=(cnt&1)?f[m]:-f[m];
		}
		printf("%lld\n",f[s]-ans);
	}
}

int main()
{
	init();
	work();
	return 0;
}

luogu P1450 [HAOI2008]硬币购物

原文:https://www.cnblogs.com/With-penguin/p/13053294.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!