zoukankan      html  css  js  c++  java
  • 【BZOJ1042】[HAOI2008]硬币购物 容斥

    【BZOJ10492】[HAOI2008]硬币购物

    Description

      硬币购物一共有4种硬币。面值分别为c1,c2,c3,c4。某人去商店买东西,去了tot次。每次带di枚ci硬币,买si的价值的东西。请问每次有多少种付款方法。

    Input

      第一行 c1,c2,c3,c4,tot 下面tot行 d1,d2,d3,d4,s,其中di,s<=100000,tot<=1000

    Output

      每次的方法数

    Sample Input

    1 2 5 10 2
    3 2 3 1 10
    1000 2 2 2 900

    Sample Output

    4
    27

    题解:先跑一边完全背包,然后对于每个询问,我们考虑容斥。

    ans=总数-至少一种硬币超限的+至少两种硬币超限的-至少三种硬币超限的+四种硬币超限的。

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    using namespace std;
    typedef long long ll;
    int n,sum,flag,s;
    ll f[100010];
    ll ans;
    int c[10],d[10];
    inline int rd()
    {
    	int ret=0,f=1;	char gc=getchar();
    	while(gc<'0'||gc>'9')	{if(gc=='-')f=-f;	gc=getchar();}
    	while(gc>='0'&&gc<='9')	ret=ret*10+gc-'0',gc=getchar();
    	return ret*f;
    }
    void dfs(int x)
    {
    	if(x==5)
    	{
    		ans+=flag*f[s-sum];
    		return ;
    	}
    	if(sum+c[x]*d[x]<=s)	sum+=c[x]*d[x],flag=-flag,dfs(x+1),sum-=c[x]*d[x],flag=-flag;
    	dfs(x+1);
    }
    int main()
    {
    	int i,j;
    	f[0]=1;
    	for(i=1;i<=4;i++)
    	{
    		c[i]=rd();
    		for(j=c[i];j<=100000;j++)	f[j]+=f[j-c[i]];
    	}
    	n=rd();
    	for(i=1;i<=n;i++)
    	{
    		for(j=1;j<=4;j++)	d[j]=rd()+1;
    		s=rd(),flag=1,ans=0;
    		dfs(1);
    		printf("%lld
    ",ans);
    	}
    	return 0;
    }
  • 相关阅读:
    查找算法(I) 顺序查找 二分查找 索引查找
    快速排序 Quick Sort
    Activity生命周期
    Android中资源文件的使用
    排序算法
    插入排序(I)Insert Sort
    Java eclipse调试技巧什么的。。
    HTTP协议解析
    python技巧26[str+unicode+codecs]
    python类库26[PySide之helloworld]
  • 原文地址:https://www.cnblogs.com/CQzhangyu/p/7367361.html
Copyright © 2011-2022 走看看