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