博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
NOI题库--砝码称重V2(多重背包2^n拆分)
阅读量:4599 次
发布时间:2019-06-09

本文共 1698 字,大约阅读时间需要 5 分钟。

以前只会写多重背包的原版,渣的不行,为了做此题不得不学习了一下,发现其实也不难,只要理解了方法就好多了(PS:其实和倍增挺像的)

8756:砝码称重V2

总时间限制: 1000ms 内存限制: 65536kB
描述
设有1g、2g、3g、5g、10g、20g的砝码各若干枚(其总重<=100,000),要求:计算用这些砝码能称出的不同重量的个数,但不包括一个砝码也不用的情况。
输入
一行,包括六个正整数a1,a2,a3,a4,a5,a6,表示1g砝码有a1个,2g砝码有a2个,……,20g砝码有a6个。相邻两个整数之间用单个空格隔开。
输出
以“Total=N”的形式输出,其中N为可以称出的不同重量的个数。
样例输入
1 1 0 0 0 0
样例输出
Total=3
提示
样例给出的砝码可以称出1g,2g,3g三种不同的重量。

多重背包的2^n拆分,就是把一种多份的物体分解成几种价值高的物体来进行01背包就好,举个栗子:

**对于数量为 n 的同种物品 k 价值为 v
可以拆分打包为 1 , 2 , 4 , 8 , 16 …… ,2^x , n的剩余数量
价值为 v , 2*v ……
例如 32 个 价值为 2 的物品可以拆为
1个价值为 1*2 的物品,
1个价值为 2*2 的物品,
1个价值为 4*2 的物品,
1个价值为 8*2 的物品,
1个价值为 16*2 的物品,
1个价值为 31*2 的物品,
用这6个物品可以组合出原先32个物品的所有状态**

下面是代码:

#include
#include
#include
#include
using namespace std;int a[1000100]={
0};int f[1000100]={
0};int zz=0;int value[7]={
0,1,2,3,5,10,20};int fm[7]={
0};int sum=0;int total=0;const int cf[] = {
1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072};//以二为底的指数为i的值 void fj(int ki,int valuei)//二进制分解的过程 { int i=0; while (cf[i] <= ki) { a[++zz]=cf[i]*valuei;//zz是一个指针,指向当前地址 ki-=cf[i]; i++; } if (ki > 0) a[++zz]=ki*valuei;}int main(){ int i,j; for (i=1;i<=6;i++) { scanf("%d",&fm[i]); sum+=fm[i]*value[i];//最高价值 fj(fm[i],value[i]); } f[0]=1; for (i=1;i<=zz;i++) for (j=sum; j>=a[i];j--) f[j]=f[j] || f[j - a[i]];//只是一个普通的01背包 for (i=1;i<=sum;i++) if (f[i]) total++; printf("%s%d","Total=",total); return 0; }

“`

转载于:https://www.cnblogs.com/DaD3zZ-Beyonder/p/5346273.html

你可能感兴趣的文章
51nod1241(连续上升子序列)
查看>>
SqlSerch 查找不到数据
查看>>
集合相关概念
查看>>
Memcache 统计分析!
查看>>
(Python第四天)字符串
查看>>
个人介绍
查看>>
使用python动态特性时,让pycharm自动补全
查看>>
MySQL数据库免安装版配置
查看>>
你必知必会的SQL面试题
查看>>
html5 Canvas绘制时钟以及绘制运动的圆
查看>>
Unity3D热更新之LuaFramework篇[05]--Lua脚本调用c#以及如何在Lua中使用Dotween
查看>>
JavaScript空判断
查看>>
洛谷 P1439 【模板】最长公共子序列(DP,LIS?)
查看>>
python timeit
查看>>
Wireless Network 并查集
查看>>
51nod 1019 逆序数
查看>>
20145202马超《JAVA》预备作业1
查看>>
云推送注意(MSDN链接)
查看>>
IDEA 生成 jar 包
查看>>
加减乘除混合版
查看>>