BZOJ1042 [HAOI2008]硬币购物 【完全背包 + 容斥】
1042: [HAOI2008]硬币购物
Time Limit: 10 Sec Memory Limit: 162 MB
Submit: 2924 Solved: 1802
[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
3 2 3 1 10
1000 2 2 2 900
Sample Output
27
首先我们一次次做背包肯定T
考虑一次性做完完全背包,每次减去不合法的方案数
显然每次 ans = f[s] - 第一样物品超过限制的方案数 - 第二样物品超过限制的方案数 - 第三样物品超过限制的方案数 - 第四样物品超过限制的方案数 + 第一二样物品超过限制的方案数 + .......
具体超过限制的方案数怎么求?以第一个物品为例,就是f[s - (d[i] + 1) * c[i]],就是我们先用上d[i] + 1个硬币,剩余的部分任意取,所得的方案数就是我们所求
这算法太巧妙了> <
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long int
#define REP(i,n) for (int i = 1; i <= (n); i++)
#define fo(i,x,y) for (int i = (x); i <= (y); i++)
#define Redge(u) for (int k = head[u]; k != -1; k = edge[k].next)
using namespace std;
const int maxn = 100005,maxm = 100005,INF = 1000000000;
inline LL read(){
LL out = 0,flag = 1;char c = getchar();
while (c < 48 || c > 57) {if (c == '-') flag = -1; c = getchar();}
while (c >= 48 && c <= 57) {out = out * 10 + c - 48; c = getchar();}
return out * flag;
}
LL f[maxn],C[5],d[5],S;
void cal(){
f[0] = 1;
for (int i = 1; i <= 4; i++)
for (int j = C[i]; j <= 100000; j++)
f[j] += f[j - C[i]];
}
int main()
{
REP(i,4) C[i] = read();
cal();
int T = read();
LL ans,flag,sum;
while (T--){
REP(i,4) d[i] = read(); S = read();
ans = f[S];
for (int s = (1 << 4) - 1; s > 0; s--){
sum = 0; flag = 1;
for (int i = 1; i <= 4; i++)
if ((1 << i - 1) & s){
sum += (d[i] + 1) * C[i];
flag = -flag;
}
if (sum <= S) ans += flag * f[S - sum];
}
printf("%lld\n",ans);
}
return 0;
}
BZOJ1042 [HAOI2008]硬币购物 【完全背包 + 容斥】的更多相关文章
- Luogu-P1450 [HAOI2008]硬币购物-完全背包+容斥定理
Luogu-P1450 [HAOI2008]硬币购物-完全背包+容斥定理 [Problem Description] 略 [Solution] 上述题目等价于:有\(4\)种物品,每种物品有\(d_i ...
- BZOJ 1042 [HAOI2008]硬币购物(完全背包+容斥)
题意: 4种硬币买价值为V的商品,每种硬币有numi个,问有多少种买法 1000次询问,numi<1e5 思路: 完全背包计算出没有numi限制下的买法, 然后答案为dp[V]-(s1+s2+s ...
- BZOJ-1042:硬币购物(背包+容斥)
题意:硬币购物一共有4种硬币.面值分别为c1,c2,c3,c4.某人去商店买东西,去了tot次.每次带di枚ci硬币,买si的价值的东西.请问每次有多少种付款方法. 思路:这么老的题,居然今天才做到. ...
- bzoj1042: [HAOI2008]硬币购物(DP+容斥)
1600+人过的题排#32还不错嘿嘿 浴谷夏令营讲过的题,居然1A了 预处理出f[i]表示购买价值为i的东西的方案数 然后每次询问进行一次容斥,答案为总方案数-第一种硬币超限方案-第二种超限方案-第三 ...
- BZOJ1042 [HAOI2008]硬币购物 完全背包 容斥原理
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1042 题目概括 硬币购物一共有4种硬币.面值分别为c1,c2,c3,c4.某人去商店买东西,去了t ...
- [BZOJ 1042] [HAOI2008] 硬币购物 【DP + 容斥】
题目链接:BZOJ - 1042 题目分析 首先 Orz Hzwer ,代码题解都是看的他的 blog. 这道题首先使用DP预处理,先求出,在不考虑每种硬币个数的限制的情况下,每个钱数有多少种拼凑方案 ...
- BZOJ1042:[HAOI2008]硬币购物(DP,容斥)
Description 硬币购物一共有4种硬币.面值分别为c1,c2,c3,c4.某人去商店买东西,去了tot次.每次带di枚ci硬币,买si的价值的东西.请问每次有多少种付款方法. Input 第一 ...
- 2019.02.09 bzoj1042: [HAOI2008]硬币购物(完全背包+容斥原理)
传送门 题意简述:有四种面值的硬币,现在qqq次询问(q≤1000)(q\le1000)(q≤1000),每次给出四种硬币的使用上限问最后刚好凑出sss块钱的方案数(s≤100000)(s\le100 ...
- bzoj1042: [HAOI2008]硬币购物
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #i ...
随机推荐
- Entity Framework Core 选择数据表的外键
entityTypeBuilder .HasOne<GeraeteArt>() .WithMany(p => p.Geraete) .HasForeignKey(b => b. ...
- nginx支持php配置
location / { root /wwwroot/phptest; index index.html index.htm index.php; } location ~ \.(php|php5)$ ...
- 180601-MySql性能监控工具MyTop
文章链接:https://blog.hhui.top/hexblog/2018/06/01/180601-MySql性能监控工具MyTop/ mysql 性能监控小工具之 mytop 参考: How ...
- selenium,unittest——驾照科目一网上答题自动化
需求很简单,所有题目全选A,然后点提交出分,校验是否到达出分这步 遇到的坑有这几个,一个是assertIn哪个是校验哪个是文本要分清,还有code的编码统一到Unicode,最后就是xpath定位各个 ...
- 第一篇 HTML基础
浏览网页,就是上网,上网的本质就是下载内容. 浏览器是个解释器,用来执行HTML.css.JS代码的. HTML,CSS, JavaScript 号称网络三剑客. 1. 浏览器发送一个域名给服务端 2 ...
- lintcode491 回文数
回文数 判断一个正整数是不是回文数. 回文数的定义是,将这个数反转之后,得到的数仍然是同一个数. 注意事项 给的数一定保证是32位正整数,但是反转之后的数就未必了. 您在真实的面试中是否遇到过这个题? ...
- DP动态规划练习
先来看一下经典的背包问题吧 http://www.cnblogs.com/Kalix/p/7617856.html 01背包问题 https://www.cnblogs.com/Kalix/p/76 ...
- hadoop问题集(1)
参考: http://dataunion.org/22887.html 1.mapreduce_shuffle does not exist 执行任何时报错: Container launch ...
- 官方文档 恢复备份指南二 Getting Started with RMAN
本章对RMAN进行基本的熟悉和了解 1.Overview of the RMAN Environment RMAN运行时需要的最小环境: target database ...
- c# 委托初窥
1.委托可以把方法当作参数在另一个方法中传递和调用 ,委托是方法的快捷方式. 2.委托是一个类. private void BeginSocketThread() { try { IPEndPoint ...