zoukankan      html  css  js  c++  java
  • BZOJ1042: [HAOI2008]硬币购物

    Description

      硬币购物一共有4种硬币。面值分别为c1,c2,c3,c4。某人去商店买东西,去了tot次。每次

    带di枚ci硬币,买s的价值的东西。请问每次有多少种付款方法。

    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
     
    题目大意:
    容量为s的背包。每个物品的体积ci和数量si,求有多少种
    方案将背包正好填满。
     
    题解:dp预处理+容斥原理
    预处理出没有数量限制下的方案数,再容斥减去超过物品数量的方案数
    总的方案数-一个物品超出限制的方案数+两个物品超出限制的方案数-三个物品超出
    限制的方案数+4个物品超出限制的方案数。
     
    代码:
    #include<iostream>
    #include<cstdio>
    using namespace std;
    
    int tot,sum;
    int c[7],d[7];
    long long ans,f[100009];
    
    void dfs(int now,int cnt,int sum){
        if(now==5){
            if(cnt&1)ans-=f[sum];
             else ans+=f[sum];
            return;
        }
        dfs(now+1,cnt,sum);
        if(sum-(d[now]+1)*c[now]>=0)
        dfs(now+1,cnt+1,sum-(d[now]+1)*c[now]);
    }
    
    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]];
        for(int i=1;i<=tot;i++){
            ans=0;
            scanf("%d%d%d%d%d",&d[1],&d[2],&d[3],&d[4],&sum);
            dfs(1,0,sum);
            cout<<ans<<endl;
        }
        return 0;
    }
  • 相关阅读:
    Cocon90.Db调用方法
    Hotmail Smtp邮箱发送的端口
    Nginx+Lua+Redis构建高并发应用
    Linux安装pear包
    Nginx中if语句中的判断条件
    SqlServer判断表、列不存在则创建
    Nginx配置参数详解
    Linux中在线安装Mysql和修改密码设置服务启动
    linux中fuser用法详解
    Java中创建访问HTTPS的自签名证书的方法
  • 原文地址:https://www.cnblogs.com/zzyh/p/7645757.html
Copyright © 2011-2022 走看看