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)的更多相关文章

  1. [Luogu P1450] [HAOI2008]硬币购物 背包DP+容斥

    题面 传送门:https://www.luogu.org/problemnew/show/P1450 Solution 这是一道很有意思的在背包里面做容斥的题目. 首先,我们可以很轻松地想到暴力做背包 ...

  2. P1450 [HAOI2008]硬币购物(完全背包+容斥)

    P1450 [HAOI2008]硬币购物 暴力做法:每次询问跑一遍多重背包. 考虑正解 其实每次跑多重背包都有一部分是被重复算的,浪费了大量时间 考虑先做一遍完全背包 算出$f[i]$表示买价值$i$ ...

  3. 洛谷—— P1450 [HAOI2008]硬币购物

    P1450 [HAOI2008]硬币购物 硬币购物一共有$4$种硬币.面值分别为$c1,c2,c3,c4$.某人去商店买东西,去了$tot$次.每次带$di$枚$ci$硬币,买$si$的价值的东西.请 ...

  4. 2021.12.06 P2511 [HAOI2008]木棍分割(动态规划)

    2021.12.06 P2511 [HAOI2008]木棍分割(动态规划) https://www.luogu.com.cn/problem/P2511 题意: 有n根木棍, 第i根木棍的长度为 \( ...

  5. 2021.12.06 P2508 [HAOI2008]圆上的整点(数论+ π )

    2021.12.06 P2508 [HAOI2008]圆上的整点(数论+ \(\pi\) ) https://www.luogu.com.cn/problem/P2508 题意: 求一个给定的圆 \( ...

  6. Bzoj 1042: [HAOI2008]硬币购物 容斥原理,动态规划,背包dp

    1042: [HAOI2008]硬币购物 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1747  Solved: 1015[Submit][Stat ...

  7. 洛谷P1450 [HAOI2008]硬币购物

    题目描述 硬币购物一共有4种硬币.面值分别为c1,c2,c3,c4.某人去商店买东西,去了tot次.每次带di枚ci硬币,买si的价值的东西.请问每次有多少种付款方法. 输入输出格式 输入格式: 第一 ...

  8. P1450 [HAOI2008]硬币购物

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

  9. Luogu P1450 [HAOI2008]硬币购物 背包+容斥原理

    考虑如果没有个数的限制,那么就是一个完全背包,所以先跑一个完全背包,求出没有个数限制的方案数即可. 因为有个数的限制,所以容斥一下:没有1个超过限制的方案=至少0个超过限制-至少1个超过限制+至少2个 ...

随机推荐

  1. Spring Boot整合Redis-转载

    Spring Boot整合Redis的三中方式的博客: https://wangsong.blog.csdn.net/article/details/103210490 使用spring.cache. ...

  2. Java的http post请求01之HttpURLConnection

    package com.ricoh.rapp.ezcx.iwbservice.webservice; import java.io.BufferedOutputStream; import java. ...

  3. 亚马逊云储存器S3 BCUKET安全性学习笔记

    亚马逊云储存器S3 BCUKET安全性学习笔记 Bugs_Bunny CTF – Walk walk CTF 昨天玩了会这个比赛,碰到这题是知识盲点,来记录一下. 先从题目看起吧. http://ww ...

  4. DC-1

    靶机准备 导入虚拟机设置网络为NAT kali:192.168.164.137 扫描获得靶机ip:192.168.164.182 netdiscover -r 192.168.164.0/24 渗透测 ...

  5. 变量 Java day 5

    Java 第五天的学习 变量 变量注意事项 变量的底层 ASCII编码表 1.什么是变量? 概念:变量及代数. 在Java中,变量分为两种:基本类型的变量和引用类型的变量 1>基本类型的变量:必 ...

  6. (bzoj4408)[FJOI2016]神秘数(可持久化线段树)

    (bzoj4408)[FJOI2016]神秘数(可持久化线段树) bzoj luogu 对于一个区间的数,排序之后从左到右每一个数扫 如果扫到某个数a时已经证明了前面的数能表示[1,x],那么分情况: ...

  7. 超硬核解析!Apache Hudi灵活的Payload机制

    Apache Hudi 的Payload是一种可扩展的数据处理机制,通过不同的Payload我们可以实现复杂场景的定制化数据写入方式,大大增加了数据处理的灵活性.Hudi Payload在写入和读取H ...

  8. JDBC 能否处理 Blob 和 Clob?

    Blob 是指二进制大对象(Binary Large Object),而 Clob 是指大字符对象 (Character Large Objec),因此其中 Blob 是为存储大的二进制数据而设计的, ...

  9. Dubbo 如何停机?

    Dubbo 是通过 JDK 的 ShutdownHook 来完成优雅停机的,所以如果使用 kill -9 PID 等强制关闭指令,是不会执行优雅停机的,只有通过 kill PID 时,才 会执行.

  10. synchronized的原理

    synchronized的使用 synchronized是一个java中的关键字,是基于JVM层面的,用于保证java的多线程安全,它具有四大特性,可用于完全替代volatile: 原子性:所谓原子性 ...