[Bzoj 1192][HNOI2006]鬼谷子的钱袋(二进制优化多重背包)
(人生第一篇bzoj题解有点激动
首先介绍一下题目:
看它题目那么长,其实意思就是给定一个数a,求将其拆分成n个数,通过这n个数可以表示出1~a中所有数的方案中,求最小的n。
您看懂了嘛?不懂咱来举个栗子:
3可以变为(1,2)两个数(废话,我当然知道),使1,2可以表示出1,2,3这些数字。看到这道题就想到了不久前看到的二进制优化多重背包。简直一模一样。
我们想我们对于一个数P。我们可以将其分成两部分(1~P/2)与(P/2+1,P),我们思考:假设我们已经知道(1~P/2)至少需要m个数,那么我们完全可以在左区间的基础上添加一个P/2这个数,使这m+1个数可以表示(1~P)的所有数,因为(1+P/2~P/2+P/2)=(P/2+1~P)。
我们其实又可以通过手+草稿纸发现关于一个P的最小值n是有(1~P)的左半边区间(1~P/2)的最小值+1有关,而(1~P/2)的最小值又与它本身的左半边区间的值有关,所以事实上这是一个可以递推的过程。
然后我们归纳总结一下——P与P/2有关,P/2又与P/4有关,很容易联想到二进制。我们只要手算过后稍一扩展我们便会发现——关于一个数P,我们使一个数s满足2s -1<P,注意严格小于P,即s为log2(P),那么这一个数P可以被1,2,4.......2s-1,P-2s +1 分解。
那么其实我们很快就可以知道一个数P所对应最小n了,其实就是log2(P)+1.那么这道题一下变得简单了起来,贴代码
#include<iostream>
#include<cmath>
#include<cstdio>
using namespace std;
int main()
{
long long a;
scanf("%lld",&a);
printf("%lld",(long long )log2(a)+1);
}
鬼谷子的钱袋
其实这道题在luogu上有加强版本https://www.luogu.org/problem/P2320,其要求输出每个钱袋的数量,这道题也很简单,我们通过上面的推理先求出S,再以此求出1~2s-1 和P-2s+1再排序输出即可(据说原本只有算n,luogu加上了这道题,然而数据貌似有锅)
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
long long p,s,k;
int main()
{
scanf("%lld",&p);
printf("%lld\n",(long long)log2(p)+1);
s=log2(p);
k=p-(1<<s)+1;
for(long long i=0;i<=s-1;i++)
{
if(1<<i>k&&k!=0)
{
printf("%lld ",k);
k=0;
}
printf("%lld ",1<<i);
}
if(k!=0)
printf("%lld ",k);
return 0;
}
鬼谷子的钱袋(加强版
接下来简单描述一下标题所写的二进制优化多重背包
一般来说我们的多重背包的思路是枚举取n个同种物品,转化为01背包
那这样的时间复杂度 O(NV*∑(V/W[i])).(V为体积,W[i]为每件的费用)
但假如我们将每件物品都像鬼谷子的钱袋一样二进制拆分,那每一个物品都会被拆成log2(W[i])+1个物品
那这样再做01背包所要的时间复杂度为 O(V*log(W[i])+V)(PS:这个时间复杂度有可能写错了,但是应该差不多)
关于二进制优化多重背包以后我会再写一篇博客来讲,这篇主要的是题解hhh
您理解了嘛,慢走。
不理解的可以加qq2733524923我们一起探讨哦
[Bzoj 1192][HNOI2006]鬼谷子的钱袋(二进制优化多重背包)的更多相关文章
- BZOJ 1192: [HNOI2006]鬼谷子的钱袋 数学结论
1192: [HNOI2006]鬼谷子的钱袋 Description 鬼谷子非常聪明,正因为这样,他非常繁忙,经常有各诸侯车的特派员前来向他咨询时政.有一天,他在咸阳游历的时候,朋友告诉他在咸阳最大的 ...
- BZOJ 1192: [HNOI2006]鬼谷子的钱袋(新生必做的水题)
1192: [HNOI2006]鬼谷子的钱袋 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 3557 Solved: 2596[Submit][St ...
- BZOJ 1192 [HNOI2006]鬼谷子的钱袋:二进制 砝码称重问题
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1192 题意: 鬼谷子带了a元钱,他要把a元钱分装在小袋子中,使得任意不大于a的数目的钱,都 ...
- bzoj 1192: [HNOI2006]鬼谷子的钱袋 思维_二进制
十分巧妙的一道题. 考虑当前凑出$[1,i/2)$,那么再有一个 $i/2$,就可以凑出 [i/2+1,i). 注意,这里的 $i$ 都是 2 的 $k$ 次幂. 于是,我们只要找到 $i$ 使得 2 ...
- BZOJ 1192: [HNOI2006]鬼谷子的钱袋 [娱乐]
题意: n个数分组,使得小于n的每个数都能表示出来,最少几组 就是“最优集合”的超级弱化版.....每次+=now+1 然后一个貌似科学的方法是n二进制拆分 #include <iostream ...
- 1192: [HNOI2006]鬼谷子的钱袋
1192: [HNOI2006]鬼谷子的钱袋 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 3530 Solved: 2575[Submit][St ...
- poj1014二进制优化多重背包
Dividing Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 53029 Accepted: 13506 Descri ...
- 51nod 1086 背包问题 V2(二进制优化多重背包)
题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1086 题解:怎么用二进制优化多重背包,举一个例子就明白了. ...
- POJ - 1276 二进制优化多重背包为01背包
题意:直接说数据,735是目标值,然后3是后面有三种钱币,四张125的,六张五块的和三张350的. 思路:能够轻易的看出这是一个多重背包问题,735是背包的容量,那些钱币是物品,而且有一定的数量,是多 ...
随机推荐
- 【Java技术专题】「性能优化系列」针对Java对象压缩及序列化技术的探索之路
序列化和反序列化 序列化就是指把对象转换为字节码: 对象传递和保存时,保证对象的完整性和可传递性.把对象转换为有字节码,以便在网络上传输或保存在本地文件中: 反序列化就是指把字节码恢复为对象: 根据字 ...
- Golang通脉之函数
函数是组织好的.可重复使用的.用于执行指定任务的代码块. Go语言中支持函数.匿名函数和闭包,并且函数在Go语言中属于"一等公民". 函数定义 Go语言中定义函数使用func关键字 ...
- 2021能源PWN wp
babyshellcode 这题考无write泄露,write被沙盒禁用时,可以考虑延时盲注的方式获得flag,此exp可作为此类型题目模版,只需要修改部分参数即可,详细见注释 from pwn im ...
- 【UE4】GAMES101 图形学作业1:mvp 模型、视图、投影变换
总览 到目前为止,我们已经学习了如何使用矩阵变换来排列二维或三维空间中的对象.所以现在是时候通过实现一些简单的变换矩阵来获得一些实际经验了.在接下来的三次作业中,我们将要求你去模拟一个基于CPU 的光 ...
- 如何从一台OPC Server访问多个PLC
项目中遇到如下情况: 1. 整条生产线由多个PLC分别控制,但是所有PLC在同一个局域网内.PLC采用西门子的S7-200 Smart 2. 客户希望在操作工站的电脑(跟PLC在同一个局域网内)上提供 ...
- 基于自定义Validator来验证枚举类型
基于自定义Validator来验证枚举类型 一.背景 二.技术要点 三.实现一个自定义枚举校验. 1.需求. 2.实现步骤 1.自定义一个 Sex 枚举. 2.自定义一个 Enum 注解 3.编写具体 ...
- evaluate-reverse-polist-notation leetcode C++
Evaluate the value of an arithmetic expression in Reverse Polish Notation. Valid operators are+,-,*, ...
- cf12E Start of the season(构造,,,)
题意: 给一个偶数N. 构造出一个矩阵. 满足:主对角线上全为0.每一行是0~N-1的一个全排列.矩阵关于主对角线对称. 思路: 觉得是智商题,,,,看完题解后觉得不难,但是我就是没想出来.只想到了前 ...
- Delphi的手机程序隐藏顶部信号栏
把TForm的BorderStyle设置为None 记之!
- clnt_create: RPC: Port mapper failure - Unable to receive: errno 113 (No route to host)
修改文件 /etc/sysconfig/nfs将#MOUNTD_PORT=892开启防火墙端口:firewalld-cmd --add-port=892/tcp