• BZOJ 1042 HAOI2008 硬币购物


    1042: [HAOI2008]硬币购物
    
    Time Limit: 10 Sec  Memory Limit: 162 MB
    Submit: 2903  Solved: 1785
    [Submit][Status][Discuss]
    Description
    
      硬币购物一共有4种硬币。面值分别为c1,c2,c3,c4。某人去商店买东西,去了tot次。每次带di枚ci硬币,买s
    i的价值的东西。请问每次有多少种付款方法。
    
    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
    DP预处理+容斥原理。
    以前没写过容斥原理,所以这里写下笔记吧。
    若用一个01串表示方案种类,第I位为1表示满足D[I]条件,为0表示不满足的话。
    那么,我们要求的即是1111。
    显然,就是 所有情况(至少有0个0的情况)-至少有一个0的情况+至少有两个0的情况...【减加减加】
    即 ANS=0个0=(0个0,1个0,2个0..)-(1个0,2个0,3个0..)+(2个0,3个0..)..
    也就是说,减去所有至少偶奇数个0的情况,加上所有至少偶数个0的情况。
    这个可以用DFS来做。
    每一层即一个位I,可以转移到不受限制的情况(这一位0或1)或者(这一位0)的情况。分别不改颜色和改颜色。
    也可以直接循环去枚举
    我代码写的是循环去枚举要还是删掉
    还是太弱了QAQ
     1 #include <bits/stdc++.h>
     2 #define ll long long
     3 using namespace std;
     4 inline ll read(){
     5     ll x=0;ll f=1;char ch=getchar();
     6     while(!isdigit(ch)){if(ch=='-') f=-1;ch=getchar();}
     7     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
     8     return x*f;
     9 }
    10 ll f[300010]={};
    11 int c[5],d[5];
    12 namespace zhangenming{
    13     void init(){
    14          c[1]=read();c[2]=read();c[3]=read();c[4]=read();
    15          f[0]=1;
    16          for(int i=1;i<=4;i++){
    17              for(int j=c[i];j<=200100;j++){
    18                  f[j]+=f[j-c[i]];
    19             }
    20         }
    21     }
    22     void solve(){
    23         ll tot=read();
    24         for(int i=1;i<=tot;i++){
    25             for(int i=1;i<=4;i++){
    26                 d[i]=read();
    27             }
    28          ll ans=0;
    29          ll s=read();
    30          if(s>d[1]*c[1]+d[2]*c[2]+d[3]*c[3]+d[4]*c[4]){
    31             printf("%lld
    ",ans);continue;
    32          }
    33           ans=f[s];
    34           for(ll i=1;i<=4;i++){
    35             if(s>=(d[i]+1)*c[i]) ans-=f[s-(d[i]+1)*c[i]];
    36           } 
    37           for(ll i=1;i<=4;i++){
    38               for(ll j=i+1;j<=4;j++){
    39                   if(s>=(d[i]+1)*c[i]+(d[j]+1)*c[j]) ans+=f[s-(d[i]+1)*c[i]-(d[j]+1)*c[j]];
    40               }
    41           }
    42          for(ll i=1;i<=4;i++){
    43               for(ll j=i+1;j<=4;j++){
    44                   for(ll k=j+1;k<=4;k++){
    45                       if(s>=(d[i]+1)*c[i]+(d[j]+1)*c[j]+(d[k]+1)*c[k]) ans-=f[s-(d[i]+1)*c[i]-(d[j]+1)*c[j]-(d[k]+1)*c[k]];
    46                   }
    47               }
    48           }
    49          if(s>=((d[1]+1)*c[1]+(d[2]+1)*c[2]+(d[3]+1)*c[3]+(d[4]+1)*c[4])){
    50             ans+=f[s-(d[1]+1)*c[1]-(d[2]+1)*c[2]-(d[3]+1)*c[3]-(d[4]+1)*c[4]];
    51          }
    52          
    53          printf("%lld
    ",ans);
    54         }
    55     }
    56 }
    57 int main(){
    58     //freopen("A+B.in","r",stdin);
    59     //freopen("A+B.out","w",stdout);
    60     using namespace zhangenming;
    61     init();
    62     solve();
    63     return 0;
    64 }
    代码
  • 相关阅读:
    SQL的增删改查
    SQL语句的分类
    创建新DB和新用户&DBeaver连接
    jQuery css() 方法:设置或返回被选元素的一个或多个样式属性
    jQuery
    jQuery
    jQuery
    jQuery
    jQuery
    jQuery
  • 原文地址:https://www.cnblogs.com/something-for-nothing/p/7857282.html
Copyright © 2020-2023  润新知