码迷,mamicode.com
首页 > 其他好文 > 详细

BZOJ 1042: [HAOI2008]硬币购物(容斥原理)

时间:2017-07-31 15:51:24      阅读:106      评论:0      收藏:0      [点我收藏+]

标签:ems   技术   printf   oid   const   name   www   pll   typedef   

http://www.lydsy.com/JudgeOnline/problem.php?id=1042

题意:

技术分享

 

思路:

如果不考虑硬币个数的话,这就是一道完全完全背包的题目。

直接求的话行不通,于是这里要用容斥原理来做。

简单来说,ans=一种没超-一种硬币超+两种硬币超-三种硬币超+四种硬币超。

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<cstdio>
 5 #include<sstream>
 6 #include<vector>
 7 #include<stack>
 8 #include<queue>
 9 #include<cmath>
10 #include<map>
11 #include<set>
12 using namespace std;
13 typedef long long ll;
14 typedef pair<int,int> pll;
15 const int INF = 0x3f3f3f3f;
16 const int maxn = 100000 + 5;
17 
18 int s;
19 ll ans;
20 int c[5],d[5];
21 int f[maxn];
22 
23 void init()
24 {
25     memset(f,0,sizeof(f));
26     f[0]=1;
27     for(int i=1;i<=4;i++)
28     {
29         for(int j=c[i];j<=maxn;j++)
30             f[j]+=f[j-c[i]];
31     }
32 }
33 
34 void dfs(int cur, int cnt, ll sum)
35 {
36     if(sum<0) return;
37     if(cur==5)
38     {
39         if(cnt&1)  ans-=f[sum];
40         else ans+=f[sum];
41         return;
42     }
43     dfs(cur+1,cnt+1,sum-(d[cur]+1)*c[cur]);
44     dfs(cur+1,cnt,sum);
45 }
46 
47 int main()
48 {
49     //freopen("in.txt","r",stdin);
50     int T;
51     for(int i=1;i<=4;i++)  scanf("%d",&c[i]);
52     scanf("%d",&T);
53     init();
54     while(T--)
55     {
56         for(int i=1;i<=4;i++)  scanf("%d",&d[i]);
57         scanf("%d",&s);
58         ans=0;
59         dfs(1,0,s);
60         printf("%d\n",ans);
61     }
62     return 0;
63 }

 

BZOJ 1042: [HAOI2008]硬币购物(容斥原理)

标签:ems   技术   printf   oid   const   name   www   pll   typedef   

原文地址:http://www.cnblogs.com/zyb993963526/p/7263022.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!