[题解向] [Luogu1441] 砝码称重
\(\color{red}{\mathcal{Description}}\)
\(\color{red}{\mathcal{Solution}}\)
思路:\(01\)背包方案数 + \(bitset\) + 子集枚举
首先我的\(dfs\)菜的一匹,所以说一看这道题我就放弃了\(dfs\)
我们考虑子集枚举选取\(n-m\)个物品时的状态,然后对于每一个状态进行一次\(bool\)类型的\(01\)背包,最后统计\(max\)即可。
但是显然我们的复杂度会达到
\]
其中第一项是枚举子集的复杂度,之后是\(01\)背包方案数 + 扫一遍 + 清零+求出背包容量\(t\)的复杂度。
显然不足以\(1s\)过。那么我们不妨思考一个简单的优化,我们枚举状态从\(1 <<(n - m - 1)\)开始,因为当位数小于\(n - m\)时,永远选不够\(n-m\)个。并且我们可以预处理出每个状态的\(1\)的个数,那么我们就会有\(T(n) = 2^n-2^{n-m} +C_{n}^{m}\cdot (n \sum a_i + 3n) -> \Theta(max(2^n - 2^{n-m}, C_{n}^{m} \cdot n\sum a_i))\)
好像还可以的吧,但事实上我们还可以更优,我们直接考虑用\(bitset\)作为\(dp\)数组,然后就会有\(3 \cdot\frac{n}{32}\)的检测复杂度,好像可以优化些常数。
最后我还用了
inline int max(int a, int b) {return b - (b - a & (b - a >> 31));}
的毒瘤优化,但是依旧很慢——不过这不能阻止人类否定\(dfs\)的一家独大。
\(qwq\)
#include <bitset>
#include <cstdio>
#include <iostream>
#define MAX 5000
using namespace std ;
int i, j, k, d, t ; bitset <MAX> dp ;
int N, M, base[MAX], Len[MAX << 8], Max, Ans ;
inline int max(int a, int b) {return b - (b - a & (b - a >> 31));}
int main(){
cin >> N >> M ; d = N - M, Max = (1 << N) - 1 ;
for (i = 1 ; i <= N ; ++ i) cin >> base[i] ;
for (i = 1 ; i <= Max ; ++ i) Len[i] = Len[i - (i & -i)] + 1 ;
for (i = 1 << d - 1; i <= Max ; ++ i){
if(Len[i] == d){
dp.reset(), dp[0] = 1, t = 0 ;
for (j = 0 ; j < N ; ++ j) t += (1 << j & i) ? base[j + 1] : 0 ;
for (k = 0 ; k < N ; ++ k)
for (j = t ; j >= base[k + 1] ; -- j)
dp[j] = (1 << k & i) ? dp[j] : (dp[j] | dp[j - base[k + 1]]) ;
Ans = max(Ans, (int)dp.count() - 1) ;
}
}
cout << Ans << endl ; return 0 ;
}
[题解向] [Luogu1441] 砝码称重的更多相关文章
- luogu1441 砝码称重
搜索+背包就是了 #include <iostream> #include <cstring> #include <cstdio> using namespace ...
- 51nod 1837 砝码称重【数学,规律】
题目链接:51nod 1837 砝码称重 小 Q 有 n 个砝码,它们的质量分别为 1 克. 2 克.……. n 克. 他给 i 克的砝码标上了编号 i (i = 1, 2, ..., n),但是编号 ...
- Codevs 2144 砝码称重 2
2144 砝码称重 2 时间限制: 1 s 空间限制: 16000 KB 题目等级 : 钻石 Diamond 题解 题目描述 Description 有n个砝码,现在要称一个质量为m ...
- BZOJ 1192 [HNOI2006]鬼谷子的钱袋:二进制 砝码称重问题
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1192 题意: 鬼谷子带了a元钱,他要把a元钱分装在小袋子中,使得任意不大于a的数目的钱,都 ...
- codevs 2144 砝码称重2
传送门 2144 砝码称重 2 时间限制: 1 s 空间限制: 16000 KB 题目等级 : 钻石 Diamond 题解 题目描述 Description 有n个砝码,现在要称一个质量为m ...
- P2347 砝码称重(动态规划递推,背包,洛谷)
题目链接:P2347 砝码称重 参考题解:点击进入 纪念我第一道没理解题意的题 ''但不包括一个砝码也不用的情况'',这句话我看成了每个砝码起码放一个 然后就做不出来了 思路: 1.这题数据很小,10 ...
- 51 Nod 1449 砝码称重
1449 砝码称重 题目来源: CodeForces 基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题 收藏 关注 现在有好多种砝码,他们的重量是 w0,w1, ...
- NOI题库--砝码称重V2(多重背包2^n拆分)
以前只会写多重背包的原版,渣的不行,为了做此题不得不学习了一下,发现其实也不难,只要理解了方法就好多了(PS:其实和倍增挺像的) 8756:砝码称重V2 总时间限制: 1000ms 内存限制: 655 ...
- Codevs No.2144 砝码称重2
2016-05-31 22:01:16 题目链接: 砝码称重2 (Codevs No.2144) 题目大意: 给定N个砝码,求称出M的重量所需砝码最小个数 解法: 贪心 使砝码数量最小,当然是每个砝码 ...
随机推荐
- scrapy 使用
启动方式: 写一个启动文件,与配置文件同级 from scrapy.cmdline import execute import sys,os sys.path.append(os.path.dir ...
- Window与Document
Window 表示一个包含DOM文档的窗口,其 document 属性指向窗口中载入的 DOM文档.使用 document.defaultView 属性可以获取指定文档所在窗口.window作为全局变 ...
- 数据库-io检测工具sqldeveloper-18.2.0.183.1748-x64 下载链接
链接:https://pan.baidu.com/s/1R0ujc_9aXdc5O5i1nhNAlA 提取码:o6is
- Java I/O系统学习系列三:I/O流的典型使用方式
尽管可以通过不同的方式组合IO流类,但我们可能也就只用到其中的几种组合.下面的例子可以作为典型的IO用法的基本参考.在这些示例中,异常处理都被简化为将异常传递给控制台,但是这只有在小型示例和工具中才适 ...
- 自回归(auto-regression)机制
在每个新单词产生后,该单词就被添加在之前生成的单词序列后面,这个序列会成为模型下一步的新输入.这种机制叫做自回归(auto-regression),同时也是令 RNN 模型效果拔群的重要思想. GPT ...
- Winform中实现根据配置文件重新加载ZedGraph属性的实现思路
场景 Winforn中设置ZedGraph曲线图的属性.坐标轴属性.刻度属性: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/10 ...
- 批量操作mysql数据库表
SELECT CONCAT('truncate TABLE ',table_schema,'.',TABLE_NAME, ';') FROM INFORMATION_SCHEMA.TABLES WHE ...
- java request.getInputStream中文乱码解决方案
请求时要指定为UTF-8,中文码码完美解决 /** * * 得到请求body字符串,一般用于content-type:application/json * */ public static Strin ...
- Oracle PLSQL游标、游标变量的使用
参考文章:https://www.cnblogs.com/huyong/archive/2011/05/04/2036377.html 在 PL/SQL 程序中,对于处理多行记录的事务经常使用游标来实 ...
- 高并发&高可用系统的常见应对策略
解耦神器:MQ MQ是分布式架构中的解耦神器,应用非常普遍.有些分布式事务也是利用MQ来做的.由于其高吞吐量,在一些业务比较复杂的情况,可以先做基本的数据验证,然后将数据放入MQ,由消费者异步去处理后 ...