NOI題庫 砝碼稱重V2(多重揹包2 n拆分)

2022-05-20 09:43:51 字數 1685 閱讀 1028

以前只會寫多重揹包的原版,渣的不行,為了做此題不得不學習了一下,發現其實也不難,只要理解了方法就好多了(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]=;

int f[1000100]=;

int zz=0;

int value[7]=;

int fm[7]=;

int sum=0;

int total=0;

const

int cf = ;

//以二為底的指數為i的值

void fj(int ki,int valuei)//二進位制分解的過程

if (ki > 0)

a[++zz]=ki*valuei;

}int main()

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; }

1086 揹包問題 V2(多重揹包)

有n種物品,每種物品的數量為c1,c2 cn。從中任選若干件放在容量為w的揹包裡,每種物品的體積為w1,w2 wn wi為整數 與之相對應的價值為p1,p2 pn pi為整數 求揹包能夠容納的最大價值。輸入第1行,2個整數,n和w中間用空格隔開。n為物品的種類,w為揹包的容量。1 n 100,1 w...

51nod 1086 揹包問題 V2 多重揹包

有n種物品,每種物品的數量為c1,c2.cn。從中任選若干件放在容量為w的揹包裡,每種物品的體積為w1,w2.wn wi為整數 與之相對應的價值為p1,p2.pn pi為整數 求揹包能夠容納的最大價值。input 第1行,2個整數,n和w中間用空格隔開。n為物品的種類,w為揹包的容量。1 n 100...

51nod 1086 揹包問題 V2(多重揹包)

51nod 1086 揹包問題 v2 多重揹包 多重揹包每種有限定的數量,可以轉化為01揹包來做。include include include include include include include using namespace std define ll long long defin...