hdu3033---加限制条件的0-1背包
2 #include<stdio.h>
3 #include<string.h>
4 ?int n,m,k,p[101],max=0,v[101];
5 ?int br[11][101],sum[11] ;
6 long f[11][10001];
7
8 int main(){
9 int i,j,x,i1;
10 while(scanf("%d%d%d",&n,&m,&k)!=EOF)
11 {
12 memset(sum,0,sizeof(sum));
13 for(i=1;i<=n;i++)
14 {
15 scanf("%d%d%d",&x,&p[i],&v[i]);
16 br[x][++sum[x]]=i;
17 }
18 for(i=1;i<=k;i++)
19 for(j=1;j<=m;j++)
20 f[i][j]=-1;
21 for(j=1;j<=m;j++)
22 f[0][j]=0;
23 for(i=1;i<=k;i++)---------表示品牌編號(hào)
24 for(i1=1;i1<=sum[i];i1++)--------表示i品牌下的產(chǎn)品編號(hào)
25 for(j=m;j>=1;j--)-------------表示可以花費(fèi)的錢(qián),注意要倒寫(xiě)
26 {
27 if(j>=p[br[i][i1]])
28 {
29 if(f[i][j-p[br[i][i1]]]!=-1&&f[i][j]<f[i][j-p[br[i][i1]]]+v[br[i][i1]])
30 f[i][j]=f[i][j-p[br[i][i1]]]+v[br[i][i1]];
31 if(f[i-1][j-p[br[i][i1]]]!=-1&&f[i][j]<f[i-1][j-p[br[i][i1]]]+v[br[i][i1]])
32 f[i][j]=f[i-1][j-p[br[i][i1]]]+v[br[i][i1]];
33 }
34 }
35 if(f[k][m]<0)printf("Impossible\n");
36 else
37 printf("%d\n",f[k][m]);
38 }
39 return 0;
40 }
?
????? 程序思想:f[i][j]代表用j的價(jià)錢(qián)買(mǎi)前i個(gè)品牌可以得到的最大價(jià)值數(shù)。
?????? 賦初值:見(jiàn)18到22行
??????狀態(tài)轉(zhuǎn)移:f[i][j]可以經(jīng)過(guò)三種狀態(tài)得到————?
????? 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個(gè)產(chǎn)品,p[]是某產(chǎn)品的價(jià)格,v[]是某產(chǎn)品的價(jià)值。
????? 意思是,當(dāng)放到第i個(gè)品牌的第i1個(gè)產(chǎn)品時(shí),它的狀態(tài)等于不放第i1個(gè)產(chǎn)品,而放i1
????? 以前的i類(lèi)品牌中的某些產(chǎn)品(f[i][j]),放i類(lèi)品牌的第i1個(gè)產(chǎn)品,而不放i的其他
????? 產(chǎn)品(f[i-1][j-p[br[i][i1]]]+v[br[i][i1]]),放i類(lèi)的第i1個(gè)產(chǎn)品,同時(shí)也放i類(lèi)中i1以前
????? 的某些產(chǎn)品 (f[i][j-p[br[i][i1]]]+v[br[i][i1]] ) 。
???????
?????? 幾個(gè)問(wèn)題:
?????? 1.如何保證每一類(lèi)品牌至少放一件產(chǎn)品?
?????? 答:首先看循環(huán):
??????? 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]])----限制條件
???????在某一狀態(tài)存在的情況下(不等于-1),找出三種狀態(tài)中最大的,賦值給f[i][j] .由于開(kāi)始時(shí)所有f[i][j](i!=0)都為-1,所以i=1
?????? 更新時(shí)一定會(huì)從f[0][]開(kāi)始,而此時(shí)就可保證當(dāng)i=1時(shí),f[i][j]中所有值不為-1的狀態(tài)一定裝了品牌1的某個(gè)物品。而當(dāng)i>1時(shí),
?????? 要想得到最初的f[i][j],一定是從已經(jīng)放有前i-1個(gè)品牌的某個(gè)狀態(tài)得到的,而更新最初的f[i][j] 也一定會(huì)用到i品牌的某
?????? 個(gè)產(chǎn)品(都可由狀態(tài)轉(zhuǎn)移方程可知)。
?????? 總之,保證每一類(lèi)品牌 至少放一件產(chǎn)品是通過(guò)賦初值,條件判斷,狀態(tài)轉(zhuǎn)移三方面實(shí)現(xiàn)的。
????? 2.如何抱證每個(gè)產(chǎn)品只放一次?
??????? 答: 注意循環(huán)安排順序:將對(duì)某一品牌產(chǎn)品編號(hào)的循環(huán)放在對(duì)限制總錢(qián)數(shù)的循環(huán)之前 。
?
轉(zhuǎn)載于:https://www.cnblogs.com/aiyite826/archive/2010/07/23/1783879.html
總結(jié)
以上是生活随笔為你收集整理的hdu3033---加限制条件的0-1背包的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Linux用户和用户组管理常见问题
- 下一篇: 精彩十年(2)——阴沟里也翻船