入門多重揹包 HDU2844

2022-05-10 20:30:42 字數 2030 閱讀 5711

題目鏈結

給你若干種面值的硬幣,每種硬幣有多個,給你乙個數字m,問你能用給你的硬幣組合出和為1-m之間的幾種情況,例如1個兩元硬幣 2個一元硬幣 m=3時 就能組合出來1 2 3 答案就是三 ;m=4時,答案就是4 ;m=5時答案還是4。(難得我解釋了一次題意,hh)

如果會01揹包與完全揹包,多重揹包其實看**就能理解,難的地方只有乙個就是那個二進位制優化,昨晚問馬姐姐問到十一點多終於懂了,感謝馬姐姐,馬仙女~

多重揹包(multiplepack): 有n種物品和乙個容量為v的揹包。第i種物品最多有n[i]件可用,每件費用是c[i],價值是w[i]。求解將哪些物品裝入揹包可使這些物品的費用總和不超過揹包容量,且價值總和最大。

這題目和完全揹包問題很類似。基本的方程只需將完全揹包問題的方程略微一改即可,因為對於第i種物品有n[i]+1種策略:取0件,取1件……取n[i]件。令f[i][v]表示前i種物品恰放入乙個容量為v的揹包的最大權值,則有狀態轉移方程:

多重揹包**:

void pd(int m,int v,int w,int

num)

for(int i=1;i<=num;i<<=1

)

if(num) p01(m,num*v,num*w);

}

其實也沒多長對吧,別的不解釋,就只說說二進位制優化吧

再說二進位制優化之前,我們要先明白笨方法是什麼,這裡給出

笨方法的**:

void pd(int m,int v,int w,int

num)

for(int i=1;i<=num;i++)

}

首先我要你搞明白一件事,用這個笨方法,也能出結果,只是效率不高,我昨晚就是沒弄明白這個,所以耽誤了好久。

之所以這總方法效率不高,在於,他對每乙個i,也就是放置同種物品的個數,都從1到num遍歷了,我們這道題物品個數i最大可能是1000的,可想而知,對於每乙個i都要進行一次01揹包,效率肯定不高,,那麼為什麼二進位制優化中,只取了某幾個i(比如說num=10 的時候,i只取了1 2 4 3這四個數)來進行,卻能達到和「笨方法」一樣的效果呢?

顯然,為了保證揹包動歸結果正確,我們要考慮在揹包內放入1 , 2 3 4,,,num件某物品時的這num種情況所對應揹包的狀態,缺一不可。我們的笨方法就很直觀的達到了這種目的,下面分析「聰明辦法」為什麼能達到這種目的:

我們以10為例,第一輪01揹包i=1,如果i=1也不行那後面i肯定也都不行說明放不進去

1,i=1時只放乙個物品時的物品被拿出來了,放進去了兩個物品

2,i=1時放進去的物品沒拿出來,又放進去兩個物品

3,i=1時放進去的物品沒拿出來,i=2時的兩個物品也沒拿出來

這三種情況可能不會都出現,如果沒有出現,那就說明這種情況不會是解~

以此類推,之後i=4 ,3

可以把放進去 1 2 3 4 5 6 7 8 9 10個物品的情況統統考慮一遍,從而達到了和「笨方法」一樣的效果。

this is it.

完整**:

#include #include 

#define inf 0x3f3f3f3f

using

namespace

std;

const

int maxn=0x3f3f3f3f

;int

n,m;

int f[100010],a[110],c[110

]; void p01(int m,int v,int

w)

}void pall(int m,int v,intw)}

void pd(int m,int v,int w,int

num)

for(int i=1;i<=num;i<<=1

)

if(num) p01(m,num*v,num*w);

}int

main()

int ans=0

;

for(int i=1;i<=m;i++)

cout

}return0;

}

view code

hdu 2844 多重揹包)

思路 其實就是多重揹包的應用,只是這裡價值和重量是相等的,因此最後計數是要計價值和重量相等的個數 1 include2 include3 const int n 100010 4 using namespace std 5int n,m 67 struct nodenode n 100 11 int...

hdu2844 多重揹包

讀題能力還是不行,英文水平不夠,只能靠翻譯 華沙人用硬幣。他們有價值a1 a2 a3的硬幣 一枚銀幣。一天,希比克斯開啟錢包,發現裡面有一些硬幣。他決定在附近的一家商店買一塊非常好的手錶。他想支付確切的 不找零 他知道 不會超過m,但他不知道手錶的確切 你要寫乙個程式,它讀取n,m,a1,a2,a3...

hdu 2844 多重揹包

真爽啊 打完一把絕對carry的亞索 來做這題 一發ac touch me 這題 反正資料很大 不用二進位制拆分 肯定tle的 反正 二進位制拆分 很簡單的啊 不會的 現在看我 學下就好了。1 include 2 include 3 using namespace std 45 const int ...