zoukankan      html  css  js  c++  java
  • Luogu P1450 [HAOI2008]硬币购物


    Luogu P1450 [HAOI2008]硬币购物

    解析

    • 刚开始以为是道多重背包题,但看到数据范围后发现此题并不简单
    • 首先用完全背包预处理出硬币数量不限制时需要钱的数量 $ leq 100000 $ 的所有情况
    • 发现在预处理中会有不合法的情况,也就是超过硬币数量限制的情况,需要减去
    • 容斥原理,减去一枚硬币不合法的情况,加回两枚硬币不合法的情况,减去三枚硬币不合法的情况,加回四枚硬币不合法的情况,这里的处理就是通过 $ pm f[s - c_i * (d_i + 1)] $ 得到,可以通过枚举子集实现

    Code

    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define LL long long
    using namespace std;
    int tot,s,t,c[5],d[5];
    LL ans,f[100005];
    int main()
    {
    	scanf("%d%d%d%d%d",&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("%d%d%d%d%d",&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 frog=0;
    			for(int j=1;j<=4;j++)
    			{
    				if(i&(1<<(j-1)))
    				{
    					frog^=1;
    					res+=c[j]*(d[j]+1);
    				}
    			}
    			if(s>=res)
    			{
    				if(frog) ans-=f[s-res];
    				else ans+=f[s-res];
    			}
    		}
    		printf("%lld
    ",ans);
    	}
    	return 0;
    }
    
  • 相关阅读:
    基本HAL库操作函数整理
    oled(iic协议)
    Uart串口中断收发
    博主回来啦
    博主的冒泡1
    AFO

    起床困难综合症
    费解的开关
    数独
  • 原文地址:https://www.cnblogs.com/Hawking-llfz/p/11589670.html
Copyright © 2011-2022 走看看