hdu3033 加限制條件的0 1揹包

2022-09-01 12:33:10 字數 2019 閱讀 2581

**

1

#include

<

stdlib.h

>

2#include

<

stdio.h

>

3#include

<

string

.h>

4int

n,m,k,p[

101],max=0

,v[101];5

intbr[

11][

101],sum[

11] ;

6long

f[11

][10001];7

8int

main()

18for(i=

1;i<=

k;i++)19

for(j=1

;j<=

m;j++)20

f[i][j]=-1

;21for(j=1

;j<=

m;j++)22

f[0][j]=0

; 23

for(i=1

;i<=

k;i++

)---------

表示品牌編號

24for

(i1=

1;i1

<=

sum[i];i1++)

--------

表示i品牌下的產品編號

25for(j=

m;j>=1;j

--)-------------

表示可以花費的錢,注意要倒寫

2634

}

35if

(f[k][m]

<

0)printf(

"impossible\n");

36else

37printf(

"%d\n

",f[k][m]);

38}

39return0;

40}

程式思想:f[i][j]代表用j的價錢買前i個品牌可以得到的最大價值數。

賦初值:見18到22行

狀態轉移:f[i][j]可以經過三種狀態得到———— 

f[i][j],f[i-1][j-p[br[i][i1]]]+v[br[i][i1]],f[i][j-p[br[i][i1]]]+v[br[i][i1]]

br[i][i1]代表第i種品牌的第i1個產品,p是某產品的**,v是某產品的價值。

意思是,當放到第i個品牌的第i1個產品時,它的狀態等於不放第i1個產品,而放i1

以前的i類品牌中的某些產品(f[i][j]),放i類品牌的第i1個產品,而不放i的其他

產品(f[i-1][j-p[br[i][i1]]]+v[br[i][i1]]),放i類的第i1個產品,同時也放i類中i1以前

的某些產品 (f[i][j-p[br[i][i1]]]+v[br[i][i1]] ) 。

幾個問題:

1.如何保證每一類品牌至少放一件產品?

答:首先看迴圈:

for(i=1;i<=k;i++)

for(i1=1;i1<=sum[i];i1++)

for(j=m;j>=1;j--)

if(j>=p[br[i][i1]])----限制條件

在某一狀態存在的情況下(不等於-1),找出三種狀態中最大的,賦值給f[i][j] .由於開始時所有f[i][j](i!=0)都為-1,所以i=1

更新時一定會從f[0]開始,而此時就可保證當i=1時,f[i][j]中所有值不為-1的狀態一定裝了品牌1的某個物品。而當i>1時,

要想得到最初的f[i][j],一定是從已經放有前i-1個品牌的某個狀態得到的,而更新最初的f[i][j] 也一定會用到i品牌的某

個產品(都可由狀態轉移方程可知)。

總之,保證每一類品牌 至少放一件產品是通過賦初值,條件判斷,狀態轉移三方面實現的。

2.如何抱證每個產品只放一次?

答: 注意迴圈安排順序:將對某一品牌產品編號的迴圈放在對限制總錢數的迴圈之前 。

分組揹包 hdu3033

題意 有k種品牌的鞋子,要每種都收集到至少乙個,有n雙鞋子,給出輸入 屬於那種品牌,花費,收藏價值。每雙鞋子只可以買一雙,問收藏價值最大能多少 思路 既然每種只能一雙那一定01揹包。但是又要求每種必須有乙個,因此對於每種品牌的鞋子都需要進行遍歷。分析 分組揹包問題其實只是將01揹包問題使用二維化陣列...

hdu 3033(分組揹包)

題意 有s款運動鞋,乙個n件,總錢數為m,求不超過總錢數且每款鞋子至少買一雙的情況下,使價值最大。如果 有一款買不到,就輸出 impossible 解題思路 分組揹包,和揹包九講裡面不同的是,這裡要每一組至少有乙個。為了保證每一組都有被取,dp i j 初始化為 1,表示前i組,揹包容量為j時可獲得...

Hdu 3033(分組揹包)

hdu 3033 1 思路 這道題要求每組至少選1個,但是每一種只能選一次 與之前分組揹包的模板不一樣的是,之前要求每組至多選1個 之前的分組揹包是 一組中 某個不同體積下 可以選的揹包是i,然後判斷這個揹包選不選 這樣保證了每次都是每個體積的情況下只能選取乙個揹包。然而這道題目要求至少選乙個揹包,...