Luogu-P1450 [HAOI2008]硬币购物-完全背包+容斥定理


【Problem Description】

【Solution】

上述题目等价于:有\(4\)种物品,每种物品有\(d_i\)个,且每种物品的体积为\(c_i\),问有多少种方法装满容量为\(s\)的背包?可以很容易想到跑多重背包即可,但是发现复杂度为\(O(4V\cdot n)\)。不可行。

题目要求的东西也等价于求以下等式有多少组满足条件的解:

\[c_1\cdot x_1+c_2\cdot x_2+c_3\cdot x_3+c_4\cdot x_4=s\\且0\le x1\le d_1,\ 0\le x_2\le d_2,\ 0\le x_3\le d_3,\ 0\le x_4\le d_4
\]

如果学过容斥定理的,就可以看出来这是容斥定理的一个模型。

即先不考虑\(x_1,x_2,x_3,x_4\)的上界限制条件,即每种物品有无限多个,那么就可以跑完全背包求得所有的方案数,令\(\overline A_1,\overline A_2,\overline A_3,\overline A_4\)分别代表\(0\le x1\le d_1,\ 0\le x_2\le d_2,\ 0\le x_3\le d_3,\ 0\le x_4\le d_4\)的条件,那么我们要求的就是满足\(\overline A_1\cap \overline A_2\cap \overline A_3\cap \overline A_4\)的方案数。有容斥原理公式得:

\[|\overline A_1\cap \overline A_2\cap \overline A_3\cap\overline A_4 |=|S|-(|A_1|+|A_2|+|A_3|+|A_4|)\\+(|A_1\cap A_2|+|A_1\cap A_3|+|A_1\cap A_4|+|A_2\cap A_3|+|A_2\cap A_4|+|A_3\cap A_4|)\\-(|A_1\cap A_2\cap A_3|+|A_1\cap A_2\cap A_4|+|A_1\cap A_3\cap A_4|+|A_2\cap A_3\cap A_4|)\\+(|A_1\cap A_2\cap A_3\cap A_4)\\
\]

对于\(|A_1|\),我们知道\(A_1\Leftrightarrow x_1\ge d_1+1\)。所以\(|A_1|\)就表示\(x_1\ge d_1+1,\ x_2,x_3,x_4\ge 0\)时以下等式的解的个数:

\[c_1\cdot x_1+c_2\cdot x_2+c_3\cdot x_3+c_4\cdot x_4=s\\且x_1\ge d_1+1, x_2,x_3,x_4\ge 0
\]

令\(z_1=x_1-(d_1+1),z_2=x_2,z_3=x_3,z_4=x_4\),则原式变为在\(z_1,z_2,z_3,z_4\ge 0\)的条件下,求以下等式解的个数:

\[c_1\cdot z_1+c_2\cdot z_2+c_3\cdot z_3+c_4\cdot z_4=s-(d_1+1)\\且x_1,x_2,x_3,x_4\ge0
\]

预处理\(10^5\)以内容量为\(i\)方案数\(dp[i]\)。则\(|A_1|=dp[s-(d_1+1)]\)。同理\(|A_i|=dp[s-(d_i+1)]\)。

对于\(|A_1\cap A_2|\)等其他子集,也用类似方法转换为完全背包的做法。因为物品数只有\(4\)个,所以用位运算枚举子集,偶加奇数减即可。详细请看代码。复杂度为\(O(4V+2^4\cdot n)\)。


【Code】

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
#define int long long
#define INF 0x3f3f3f3f
#define maxn 100005
int dp[maxn];
int c[5],d[5];
void CompleteBack(int V,int vol){ //完全背包
for(int j=vol;j<=V;j++){
dp[j]=dp[j]+dp[j-vol];
}
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(0);
cin>>c[0]>>c[1]>>c[2]>>c[3];
dp[0]=1;
for(int i=0;i<4;i++){
CompleteBack(maxn-5,c[i]);
}
int n;cin>>n;
while(n--){
cin>>d[0]>>d[1]>>d[2]>>d[3];int s;cin>>s;
int ans=0;
for(int i=0;i<(1<<4);i++){ //枚举子集
int sum=s,num=0;
for(int j=0;j<4;j++){
if(i>>j&1){
sum-=c[j]*(d[j]+1); num++;
}
}
if(sum<0) continue;
if(num&1) ans-=dp[sum]; //偶加奇减
else ans+=dp[sum];
}
cout<<ans<<endl;
}
return 0;
}

Luogu-P1450 [HAOI2008]硬币购物-完全背包+容斥定理的更多相关文章

  1. BZOJ 1042 [HAOI2008]硬币购物(完全背包+容斥)

    题意: 4种硬币买价值为V的商品,每种硬币有numi个,问有多少种买法 1000次询问,numi<1e5 思路: 完全背包计算出没有numi限制下的买法, 然后答案为dp[V]-(s1+s2+s ...

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

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

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

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

  4. Luogu P1450 [HAOI2008]硬币购物

    题目 一个很自然的想法是容斥. 假如只有一种硬币,那么答案就是没有限制的情况下买\(s\)的方案数减去强制用了\(d+1\)枚情况下买\(s\)的方案数即没有限制的情况下买\(s-c(d+1)\)的方 ...

  5. BZOJ-1042:硬币购物(背包+容斥)

    题意:硬币购物一共有4种硬币.面值分别为c1,c2,c3,c4.某人去商店买东西,去了tot次.每次带di枚ci硬币,买si的价值的东西.请问每次有多少种付款方法. 思路:这么老的题,居然今天才做到. ...

  6. [BZOJ 1042] [HAOI2008] 硬币购物 【DP + 容斥】

    题目链接:BZOJ - 1042 题目分析 首先 Orz Hzwer ,代码题解都是看的他的 blog. 这道题首先使用DP预处理,先求出,在不考虑每种硬币个数的限制的情况下,每个钱数有多少种拼凑方案 ...

  7. bzoj1042: [HAOI2008]硬币购物(DP+容斥)

    1600+人过的题排#32还不错嘿嘿 浴谷夏令营讲过的题,居然1A了 预处理出f[i]表示购买价值为i的东西的方案数 然后每次询问进行一次容斥,答案为总方案数-第一种硬币超限方案-第二种超限方案-第三 ...

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

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

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

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

随机推荐

  1. [LeetCode] 47. Permutations II 全排列 II

    Given a collection of numbers that might contain duplicates, return all possible unique permutations ...

  2. [LeetCode] 535. Encode and Decode TinyURL 编码和解码短网址

    Note: This is a companion problem to the System Design problem: Design TinyURL. TinyURL is a URL sho ...

  3. 【CUDA开发】 Check failed: error == cudaSuccess (8 vs. 0) invalid device function

    最近在复现R-CNN一系列的实验时,配置代码环境真是花费了不少时间.由于对MATLAB不熟悉,实验采用的都是github上rbg大神的Python版本.在配置Faster R-CNN时,编译没有问题, ...

  4. 使用Nginx+WordPress搭建个人网站

    背景 很多研究技术的朋友喜欢写博客.如果希望搭建一个完全属于自己的网站,也并不困难.这里简要分享一下我搭建这个博客网站的经验. 关键步骤 购买服务器.域名.DNS云解析服务 网站备案(可选) 安装Ng ...

  5. 基于 appium 的 UI 自动化测试

    其中主要的目录和文件为: /MPTestCases ----------- 存放测试用例 /errorScreenShot ------------ 用例执行失败生成的错误截图 startTest.p ...

  6. SpringBoot + Mybaties的逆向工程有数据库生成domain的过程

    环境:  jdk1.8 (适合springboot2.X以上版本) Maven(3.3.X以上) spring boot 2.1.6 Idea 2019.1\ 这里随便填 选择相应的Jar,如以下的勾 ...

  7. Linux学习-基本命令文件操作

    终端 1.多个终端 连接linux的客户端可以理解为终端. 命令:tty查看终端 2.不同终端之间的通讯 [root@wyx wyx]# echo 123 > /dev/pts/1 把123发给 ...

  8. Shell基础快速入门 了解shell运行原理

    Shell简介 Shell 是一个用 C 语言编写的程序,它是用户使用 Linux 的桥梁.Shell 既是一种命令语言,又是一种程序设计语言. Shell 是指一种应用程序,这个应用程序提供了一个界 ...

  9. DS 壹之型 头指针与头结点

    之前结合网上博客整理的笔记,希望能帮你解除疑惑!    

  10. java.lang.ClassNotFoundException: org.springframework.boot.bind.RelaxedPropertyResolver 错误解决

    1.今天在搭建SpringBoot整合 pageHelper的时候报错如下 1.1 引入依赖如下: <!-- 分页插件 --> <dependency> <groupId ...