**
1程式思想:f[i][j]代表用j的價錢買前i個品牌可以得到的最大價值數。#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}
賦初值:見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,然後判斷這個揹包選不選 這樣保證了每次都是每個體積的情況下只能選取乙個揹包。然而這道題目要求至少選乙個揹包,...