2021.12.06 P1450 [HAOI2008]硬币购物(组合数学+抽屉原理+DP)
2021.12.06 P1450 [HAOI2008]硬币购物(组合数学+抽屉原理+DP)
https://www.luogu.com.cn/problem/P1450
题意:
共有 44 种硬币。面值分别为 \(c_1,c_2,c_3,c_4\)。
某人去商店买东西,去了 \(n\) 次,对于每次购买,他带了 \(d_i\) 枚 \(i\) 种硬币,想购买 \(s\) 的价值的东西。请问每次有多少种付款方法。
分析:
设有且仅有一种硬币,价值为 \(c\) ,有 \(d\) 枚。现在想买价值为 \(s\) 的东西,在不限硬币个数的情况下的方案数为 \(f_s\) ,超出 \(d\) 枚的方案分别是取 \(d+1\) 枚、取 \(d+2\) 枚、取 \(d+3\) 枚……如果现在强制取 \(d+1\) 枚,那么再往上添一毛钱都不行!因为我们最少就取了 \(d+1\) 枚价值为 \(c\) 的硬币。
\(d+1\) 枚硬币的价值为 \(c*(d+1)\) ,还剩下的价值为 \(s-c*(d+1)\) ,剩下的无论怎么取一定会超过 \(d\) 枚硬币的方案数为 \(f_{s-c*(d+1)}\) 。因为选取价值为 \(c*(d+1)\) 硬币的方案数为 \(1\) ,即选取 \(d+1\) 枚硬币,根据乘法原理得,选取超过 \(d\) 枚硬币大的方案数为
\(ans=1*f_{s-c*(d+1)}=f_{s-c*(d+1)}\) ,
则满足条件的方案数为 \(f_s-ans\) 。
设我们有两种硬币,价值分别为 \(c_i\) 、 \(c_j\) ,分别有 \(d_i\) 枚、 \(d_j\) 枚。现在依旧想买价值为 \(s\) 的东西,超出 \(d_i\) 的方案数为 \(f_{s-c_i*(d_i+1)}\) ,超出 \(d_j\) 的方案数为 \(f_{s-c_j*(d_j+1)}\) 。但是存在即超出 \(d_i\) 又超出 \(d_j\) ,这种情况的方案数为 \(f_{s-c_i*(d_i+1)-c_j*(d_j+1)}\) 。根据容斥原理得,超出的总方案数为
\(tot=f_{s-c_i*(d_i+1)}+f_{s-c_j*(d_j+1)}-f_{s-c_i*(d_i+1)-c_j*(d_j+1)}\) ,
则满足条件的方案数为 \(f_s-tot\) 。
代码如下:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#define IOS ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std;
#define int long long
const int N=1e5+10;
int n,c[5],num[5],s,f[N];
signed main(){
IOS;
for(int i=1;i<=4;i++)cin>>c[i];
f[0]=1;
for(int i=1;i<=4;i++)for(int j=c[i];j<=N-10;j++)f[j]+=f[j-c[i]];
cin>>n;
for(int i=1;i<=n;i++){
for(int j=1;j<=4;j++)cin>>num[j];cin>>s;
int ans=f[s];
for(int k=15;k>0;k--){
int flag=0,ki=k,tot=0,aim=0;
while(ki){
++aim;
if(ki&1)tot+=(num[aim]+1)*c[aim],flag^=1;
ki>>=1;
}
if(tot>s)continue;
if(flag)ans-=f[s-tot];
else ans+=f[s-tot];
}
cout<<ans<<endl;
}
return 0;
}
2021.12.06 P1450 [HAOI2008]硬币购物(组合数学+抽屉原理+DP)的更多相关文章
- [Luogu P1450] [HAOI2008]硬币购物 背包DP+容斥
题面 传送门:https://www.luogu.org/problemnew/show/P1450 Solution 这是一道很有意思的在背包里面做容斥的题目. 首先,我们可以很轻松地想到暴力做背包 ...
- P1450 [HAOI2008]硬币购物(完全背包+容斥)
P1450 [HAOI2008]硬币购物 暴力做法:每次询问跑一遍多重背包. 考虑正解 其实每次跑多重背包都有一部分是被重复算的,浪费了大量时间 考虑先做一遍完全背包 算出$f[i]$表示买价值$i$ ...
- 洛谷—— P1450 [HAOI2008]硬币购物
P1450 [HAOI2008]硬币购物 硬币购物一共有$4$种硬币.面值分别为$c1,c2,c3,c4$.某人去商店买东西,去了$tot$次.每次带$di$枚$ci$硬币,买$si$的价值的东西.请 ...
- 2021.12.06 P2511 [HAOI2008]木棍分割(动态规划)
2021.12.06 P2511 [HAOI2008]木棍分割(动态规划) https://www.luogu.com.cn/problem/P2511 题意: 有n根木棍, 第i根木棍的长度为 \( ...
- 2021.12.06 P2508 [HAOI2008]圆上的整点(数论+ π )
2021.12.06 P2508 [HAOI2008]圆上的整点(数论+ \(\pi\) ) https://www.luogu.com.cn/problem/P2508 题意: 求一个给定的圆 \( ...
- Bzoj 1042: [HAOI2008]硬币购物 容斥原理,动态规划,背包dp
1042: [HAOI2008]硬币购物 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1747 Solved: 1015[Submit][Stat ...
- 洛谷P1450 [HAOI2008]硬币购物
题目描述 硬币购物一共有4种硬币.面值分别为c1,c2,c3,c4.某人去商店买东西,去了tot次.每次带di枚ci硬币,买si的价值的东西.请问每次有多少种付款方法. 输入输出格式 输入格式: 第一 ...
- P1450 [HAOI2008]硬币购物
题目描述 硬币购物一共有4种硬币.面值分别为c1,c2,c3,c4.某人去商店买东西,去了tot次.每次带di枚ci硬币,买si的价值的东西.请问每次有多少种付款方法. di,s<=100000 ...
- Luogu P1450 [HAOI2008]硬币购物 背包+容斥原理
考虑如果没有个数的限制,那么就是一个完全背包,所以先跑一个完全背包,求出没有个数限制的方案数即可. 因为有个数的限制,所以容斥一下:没有1个超过限制的方案=至少0个超过限制-至少1个超过限制+至少2个 ...
随机推荐
- web服务器-Nginx URL重写
web服务器-Nginx URL重写 一. URL重写介绍 和apache等web服务软件一样,rewrite的主要功能是实现URL地址的重定向.Nginx的rewrite功能需要PCRE软件的支持, ...
- [SPDK/NVMe存储技术分析]012 - 用户态ibv_post_send()源码分析
OFA定义了一组标准的Verbs,并提供了一个标准库libibvers.在用户态实现NVMe over RDMA的Host(i.e. Initiator)和Target, 少不了要跟OFA定义的Ver ...
- 对路径“C:\inetpub\wwwroot\Test\Temper\”的访问被拒绝 【已解决】
在IIS7上部署IIS站点时,出现如下错误: 对路径"C:\inetpub\wwwroot\Test\Temper\"的访问被拒绝: 原因是:程序对"C:\inetpub ...
- Hibernate的一级缓存和二级缓存有什么区别?
第一级缓存由Session实例维护,它是必选的,其中保持了Session当前所有关联实体的数据,也称为内部缓存.而第二级缓存则存在于SessionFactory层次,它是可选的.一级缓存只能为当前线程 ...
- Spring Mvc 源代码之我见 二
上一篇简单介绍了spring mvc 的一些基本内容 和DispatcherServlet 的doc.这一篇将会继续写我对Spring Mvc 源代码的理解.直接上代码: /** * This imp ...
- 数据分析之Pandas操作
Pandas pandas需要导入 import pandas as pd from pandas import Series,DataFrame import numpy as np 1 Serie ...
- scrapy框架初识及使用
一.什么是Scrapy? Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架,非常出名,非常强悍.所谓的框架就是一个已经被集成了各种功能(高性能异步下载,队列,分布式,解析,持久化等) ...
- 遇到的问题之“解决tomcat中文乱码问题”
方案1:在server.xml中添加了 URIEncoding="UTF-8" 属性 路径:C:\stop\apache-tomcat-8.5.69\conf 修改内容 如若方案1 ...
- Pandas怎样新增数据列
Pandas怎样新增数据列? 在进行数据分析时,经常需要按照一定条件创建新的数据列,然后进行进一步分析. 直接赋值 df.apply方法 df.assign方法 按条件选择分组分别赋值 0.读取csv ...
- kali Linux 渗透测试 | ARP 欺骗
目录 ARP 欺骗及其原理 ARP 欺骗实施步骤 必备工具安装 nmap 工具 dsniff 工具 driftnet 工具 ettercap 工具 ARP 欺骗测试 ARP 断网攻击 ARP 欺骗(不 ...