zoukankan      html  css  js  c++  java
  • 硬币购物

    洛谷的题

    其实也接近正解了。如果没有硬币限制的话,就是简单的背包问题。
    但现在加上限制,应该怎么办呢?
    我们要想到容斥。
    至于怎么想到的,算法标签里有。。。
    先预处理出硬币没有限制(都有十万个)的所有方案数。
    然后对于每种硬币,选了大于(d[i])个的方案都是不合法的。我们先预先选出(d[i]+1)个硬币,然后剩下的随便选,这些方案都是不合法的。剩下的随便选的方案又可以由预处理的数组得到。

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #define LL long long
    using namespace std;
    const int N = 100005;
    LL ans,f[N],tot,s,t,c[5],d[5];
    int main()
    {
    	scanf("%lld%lld%lld%lld%lld",&c[1],&c[2],&c[3],&c[4],&tot);
    	f[0]=1;
    	for(int i=1;i<=4;i++)
    	 for(int j=c[i];j<=100000;j++)
    	  f[j]+=f[j-c[i]];
    	t=(1<<4)-1;
    	while(tot--)
    	{
    		scanf("%lld%lld%lld%lld%lld",&d[1],&d[2],&d[3],&d[4],&s);
    		ans=f[s];
    		for(int i=t;i;i=(i-1)&t)
    		{
    			LL res=0;
    			bool flag=0;
    			for(int j=1;j<=4;j++)
    			{
    				if(i&(1<<(j-1)))
    				{
    					flag^=1;
    					res+=c[j]*(d[j]+1);
    				}
    			}
    			if(s>=res)
    			{
    				if(flag) ans-=f[s-res];
    				else ans+=f[s-res];
    			}
    		}
    		printf("%lld
    ",ans);
    	}
    	return 0;
    }
    
  • 相关阅读:
    一周总结
    各个方法的不同和优缺点
    随机抽签程序报告
    一周总结
    一周总结
    一周总结
    数据库基本知识
    线程相关概念
    进程相关概念
    模拟ssh实现远程执行命令(socket)
  • 原文地址:https://www.cnblogs.com/karryW/p/11721699.html
Copyright © 2011-2022 走看看