Charm Bracelet——揹包問題

 

Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u

Descriptioncss

Bessie has gone to the mall's jewelry store and spies a charm bracelet. Of course, she'd like to fill it with the best charms possible from the N (1 ≤ N ≤ 3,402) available charms. Each charm i in the supplied list has a weight Wi (1 ≤ Wi ≤ 400), a 'desirability' factor Di (1 ≤ Di ≤ 100), and can be used at most once. Bessie can only support a charm bracelet whose weight is no more than M (1 ≤ M ≤ 12,880).jquery

Given that weight limit as a constraint and a list of the charms with their weights and desirability rating, deduce the maximum possible sum of ratings.ios

Inputweb

* Line 1: Two space-separated integers: N and M
* Lines 2..N+1: Line i+1 describes charm i with two space-separated integers: Wi and Di
算法

Output學習

* Line 1: A single integer that is the greatest sum of charm desirabilities that can be achieved given the weight constraints優化

Sample Inputui

4 6
1 4
2 6
3 12
2 7

Sample Outputurl

23

 

揹包問題:spa

題目

有N件物品和一個容量爲V的揹包。第i件物品的重量是c[i],價值是w[i]。求解將哪些物品裝入揹包可以使這些物品的重量總和不超過揹包容量,且價值總和最大。

基本思路

這是最基礎的揹包問題,特色是:每種物品僅有一件,能夠選擇放或不放。
用子問題定義狀態:即f[i][v]表示前i件物品恰放入一個容量爲v的揹包能夠得到的最大價值。則其 狀態轉移方程即是:f[i][v]=max{ f[i-1][v], f[i-1][v-c[i]]+w[i] }。能夠壓縮空間, f[v]=max{f[v],f[v-c[i]]+w[i]}
這個方程很是重要,基本上全部跟揹包相關的問題的方程都是由它衍生出來的。因此有必要將它詳細解釋一下:「將前i件物品放入容量爲v的揹包中」這個子問題,若只考慮第i件物品的策略(放或不放),那麼就能夠轉化爲一個只牽扯前i-1件物品的問題。若是不放第i件物品,那麼問題就轉化爲「前i-1件物品放入容量爲v的揹包中」,價值爲f[i-1][v];若是放第i件物品,那麼問題就轉化爲「前i-1件物品放入剩下的容量爲v-c[i]的揹包中」,此時能得到的最大價值就是f [i-1][v-c[i]]再加上經過放入第i件物品得到的價值w[i]。
注意f[v]有意義當且僅當存在一個前i件物品的子集,其費用總和爲v。因此按照這個方程遞推完畢後,最終的答案並不必定是f[N] [V],而是f[N][0..V]的最大值。若是將狀態的定義中的「恰」字去掉,在轉移方程中就要再加入一項f[v-1],這樣就能夠保證f[N] [V]就是最後的答案。至於爲何這樣就能夠,由你本身來體會了。
示例:
#include"stdafx.h"
#include<iostream>
usingnamespacestd;
#defineMAXSIZE1000
intf[MAXSIZE+1],c[MAXSIZE+1],w[MAXSIZE+1];
int_main(intargc,_TCHAR*argv[])
{
intN,V;
cin>>N>>V;
inti=1;
for (;i<=N;++i)
{
cin>>c[i]>>w[i];
}
for (i=1;i<=N;++i)
{
for (intv=V;v>=c[i];--v) //c[i]可優化爲bound,bound=max{V-sumc[i,...n],c[i]}
{
f[v]=(f[v]>f[v-c[i]]+w[i])?f[v]:f[v-c[i]]+w[i];
}
}
//當i=N時,能夠跳出循環單獨計算F[V]
cout<<f[V]<< '\n' ;
system ( "pause" );
return0;
}
 
 
本題  不可用二維  二維會超內存  一維便好
代碼:
#include<stdio.h>
//#include<string.h>
int d[1300];
int w[400],v[100];
int main()
{
    int n,m,i,j;
    //memset(d,0,seizeof(d));
    scanf("%d %d",&n,&m);
    for(i=1;i<=n;i++)
        scanf("%d %d",&w[i],&v[i]);
    for(i=1;i<=n;i++)
       for(j=m;j>=w[i];j--)
           d[j]=(d[j]>d[j-w[i]]+v[i])?d[j]:d[j-w[i]]+v[i];
    printf("%d\n",d[m]);
    return 0;
}

 

1)0-1揹包問題和 零碎揹包問題是不一樣的,前者只能用動態規劃來作, 後者能夠用貪心算法。

2)動態規劃的核心是 「有多個重疊子問題」,「自底向上」解決問題。

3) 0-1揹包問題 ,W爲最大重量,n爲物體個數,求最大的價值Value,可在O(nW)的時間複雜度內解算出來。

這個題目是經典的0-1揹包問題,藉此學習0- 1揹包

 

有N件物品和一個容量爲V的揹包。第i件物品的重量是c[i],價值是w[i]。求解將哪些物品裝入揹包可以使這些物品的重量總和不超過揹包容量,且價值總和最大。
用子問題定義狀態:即f[i][v]表示前i件物品恰放入一個容量爲v的揹包能夠得到的最大價值。則其狀態轉移方程即是:f[i][v]=max{f[i-1][v],f[i-1][v-c[i]]+w[i]}。能夠壓縮空間,f[v]=max{f[v],f[v-c[i]]+w[i]}。
相關文章
相關標籤/搜索