IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 【容斥定理】【背包问题】P1450 [HAOI2008]硬币购物 -> 正文阅读

[数据结构与算法]【容斥定理】【背包问题】P1450 [HAOI2008]硬币购物

题目链接:
https://www.luogu.com.cn/problem/P1450
> 四种物品,物品的体积为,每件物品限制有件,


乍一看是多重背包的题目,没错就是多重背包,但是复杂度呢? O ( 1 0 5 ? 1 0 5 ? 1000 ) O(10^5 * 10 ^5 * 1000) O(105?105?1000)太大,必然超时

本题主要使用容斥

不明白容斥的话可以先去学一下容斥的思想及原理

用没有条件限制(物品数量限制)的答案数减去不满足限制(选择的物品数量超过了题目中的限制)的答案数就是要求(题目限制物品数量)的答案数

f [ j ] f[j] f[j]代表没有题目中的物品数量限制后的答案情况数(用完全背包去求)

本题使用枚举子集的技巧,本题可以用枚举 1 ? 15 1-15 1?15来代替

枚举子集的技巧可以先去百度学一下

for(int i = s; i ; i = (i - 1) & s)
// i代表二进制表示的就是子集

不满足限制的就是取数量大于 d [ i ] d[i] d[i]的,本题取 d [ i ] + 1 d[i] + 1 d[i]+1就是不满足限制,情况数就为 f [ s ? ( d [ i ] + 1 ) ? c [ i ] ] f[s - (d[i] + 1) * c[i]] f[s?(d[i]+1)?c[i]]

物品号未id不满足数量限制的话,它对应的不满足限制的情况数就为 f [ s ? ( d [ i d ] + 1 ) ? c [ i d ] ] f[s - (d[id] + 1) * c[id]] f[s?(d[id]+1)?c[id]]

容斥操作就是,总情况数 减去单个不满足限制的,加上两两之间不满足限制的,减去三个三个之间不满足限制的…(求集合并的运算)

如何区分不满足限制的物品数量呢?下面代码中x1代表的数量为奇数,为0的话代表的数量为偶数

#include<bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 1e5 + 5;

ll f[N];
ll c[5], d[5], s;

int main()
{
	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; j++)
			f[j] += f[j - c[i]];

	int t;
	cin >> t;
	while(t--)
	{
		cin >> d[1] >> d[2] >> d[3] >> d[4] >> s;
		ll res = f[s];
		int ss = 15;
		for(int i = ss; i ; i = (i - 1) & ss)
		{
			ll x = 0, tmp = 0;
			for(int j = 0 ; j < 4; j++)
			{
				if(i >> j & 1) 
					x ^= 1, tmp += c[j + 1] * (d[j + 1] + 1);
			}
			if(s >= tmp)
				res = x ? res - f[s - tmp] : res + f[s - tmp];
		}
		cout << res << "\n";
	}
	return 0;
}
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-04-18 18:07:49  更:2022-04-18 18:08:25 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 7:43:20-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码