• BZOJ 1042 [HAOI2008]硬币购物


    1042: [HAOI2008]硬币购物

    Time Limit: 10 Sec  Memory Limit: 162 MB
    Submit: 1446  Solved: 845
    [Submit][Status][Discuss]

    Description

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

    Input

    第一行 c1,c2,c3,c4,tot 下面tot行 d1,d2,d3,d4,s

    Output

    每次的方法数

    Sample Input

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

    Sample Output

    4
    27

    HINT

    数据规模

    di,s<=100000

    tot<=1000

    Source

    题解:神题呦。

    窝萌可以先算一个不考虑每种硬币的数量限制的情况下的背包。如果超过了限制,只要要用到D[1]+1枚硬币,剩余的硬币可以任意分配,所以方案数为 F[ S – (D[1]+1)C[1] ],当且仅当(S – (D[1]+1)C[1])>=0,否则方案数为0。套上容斥原理乱搞。

    容斥原理的tip:奇负偶正(最开始是0)

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cmath>
     4 #include<algorithm>
     5 #include<stack>
     6 #include<queue>
     7 #include<cstring>
     8 #define PAU putchar(' ')
     9 #define ENT putchar('
    ')
    10 using namespace std;
    11 typedef long long LL;
    12 const int maxn=100000+10,maxm=5;
    13 LL ans,f[maxn];
    14 int T,c[maxm],d[maxm];
    15 void dfs(int x,int k,int sum){
    16     if(sum<0)return;
    17     if(x==5){if(k&1)ans-=f[sum];else ans+=f[sum];return;}
    18     dfs(x+1,k+1,sum-(d[x]+1)*c[x]);dfs(x+1,k,sum);return;
    19 }
    20 void initpack(){
    21     f[0]=1;
    22     for(int i=1;i<=4;i++)
    23         for(int j=c[i];j<=100000;j++)
    24             f[j]+=f[j-c[i]];return;
    25 }
    26 inline int read(){
    27     int x=0,sig=1;char ch=getchar();
    28     for(;!isdigit(ch);ch=getchar())if(ch=='-')sig=0;
    29     for(;isdigit(ch);ch=getchar())x=10*x+ch-'0';
    30     return sig?x:-x;
    31 }
    32 inline void write(long long x){
    33     if(x==0){putchar('0');return;}if(x<0)putchar('-'),x=-x;
    34     int len=0;long long buf[20];while(x)buf[len++]=x%10,x/=10;
    35     for(int i=len-1;i>=0;i--)putchar(buf[i]+'0');return;
    36 }
    37 int main(){
    38     for(int i=1;i<=4;i++)c[i]=read();T=read();initpack();
    39     for(int i=1;i<=T;i++){
    40         for(int k=1;k<=4;k++)d[k]=read();
    41         ans=0;dfs(1,0,read());write(ans);ENT;
    42     }
    43     return 0;
    44 }
  • 相关阅读:
    Webpack安装及基础配置
    相机拍到了光源的灯珠图像
    面向对象特殊用法
    面向对象初始
    内置函数和必须的模块
    模块基本模式
    函数三
    函数二
    装饰器
    函数初识
  • 原文地址:https://www.cnblogs.com/chxer/p/4726930.html
Copyright © 2020-2023  润新知