01揹包和徹底揹包

01揹包爲揹包的一種;屬於動態規劃,所謂動規劃就是根據問題找出它的狀態方程,根據方程去解決問題;php

01揹包大意:數組

  假設有 N 件物品和一個容量爲 V 的揹包。第 i 件物品的費用是 c[i] ,價值是 w[i] 。求解將哪些物品裝入揹包可以使價值總和最大。less

         咱們能夠設二維數組f[i][v] 表示前 i 件物品恰放入一個容量爲 v 的揹包能夠得到的最大價值。則其狀態轉移方程即是:
f[i][v] = Max{ f[i − 1][v] ; f[i − 1][v − c[i]] + w[i]};
this

徹底揹包大意:假設有 N 種物品和一個容量爲 V 的揹包, 每種物品都有無限件可用。第 i 種物品的費用是 c[i] ,
價值是 w[i] 。 求解將哪些物品裝入揹包可以使這些物品的費用總和不超過揹包容量, 且價值總和最大。
spa

    基本思路 code

     這個問題很是相似於 01 揹包問題,所不一樣的是每種物品有無限件。也就是從每種
物品的角度考慮,與它相關的策略已並不是取或不取兩種,而是有取 0 件、取 1 件、取 2 件……等不少種。若是仍然按照解 01 揹包時的思路,令 f[i][v] 表示前 i 種物品恰放入一個容量爲 v 的揹包的最大權值。仍然能夠按照每種物品不一樣的策略寫出狀態轉移方程, 像這樣:
f[i][v] = max{f[i − 1][v − k &times; c[i]] + k &times; w[i]}     0 6<=k &times; c[i] <= v
這跟 01 揹包問題同樣有 O(VN) 個狀態須要求解,但求解每一個狀態的時間已經不是常數了,較前者複雜度較大些.
例題:orm

 

A - Bone Collectorthree

Crawling in process... Crawling failed Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u ip

Submit Status Practice HDU 2602 ci

Description

Many years ago , in Teddy’s hometown there was a man who was called 「Bone Collector」. This man like to collect varies of bones , such as dog’s , cow’s , also he went to the grave …
The bone collector had a big bag with a volume of V ,and along his trip of collecting there are a lot of bones , obviously , different bone has different value and different volume, now given the each bone’s value along his trip , can you calculate out the maximum of the total value the bone collector can get ?


 

Input

The first line contain a integer T , the number of cases.
Followed by T cases , each case three lines , the first line contain two integer N , V, (N <= 1000 , V <= 1000 )representing the number of bones and the volume of his bag. And the second line contain N integers representing the value of each bone. The third line contain N integers representing the volume of each bone.

 

Output

One integer per line representing the maximum of the total value (this number will be less than 231).

 

Sample Input

1
5 10
1 2 3 4 5
5 4 3 2 1

 

Sample Output

14

題意:

往一個男孩的包裏放物品,使其價值最大,典型的01揹包;

code:

二維數組:

#include<stdio.h>  
#include<string.h>  
#define M 1009  
typedef struct pack  
{  
    int cost;  
    int val;  
}PACK;  
int f[M][M];  
int main()  
{  
    int cas,n,v,i,j;  
  
    PACK a[M];  
    scanf("%d",&cas);  
    while(cas--)  
    {  
        scanf("%d%d",&n,&v);  
        memset(f,0,sizeof(f));  
        for(i=1;i<=n;i++)  
            scanf("%d",&a[i].val);  
        for(i=1;i<=n;i++)  
            scanf("%d",&a[i].cost);  
        for(i=1;i<=n;i++)  
            for(j=0;j<=v;j++)  
                if(j-a[i].cost>=0&&f[i-1][j]<f[i-1][j-a[i].cost]+a[i].val)  
                    f[i][j]=f[i-1][j-a[i].cost]+a[i].val;  
                else  
                    f[i][j]=f[i-1][j];  
        printf("%d\n",f[n][v]);  
    }  
    return 0;  
}

一維數組:

#include<stdio.h>
#include<string.h>
#define M 1009
typedef struct pack
{
    int cost;
    int val;
}PACK;
int main()
{
    int cas,n,v,i,j;
    int f[M];
    PACK a[M];
    scanf("%d",&cas);
    while(cas--)
    {
        scanf("%d%d",&n,&v);
        memset(f,0,sizeof(f));
        for(i=1;i<=n;i++)
            scanf("%d",&a[i].val);
        for(i=1;i<=n;i++)
            scanf("%d",&a[i].cost);
        for(i=1;i<=n;i++)
            for(j=v;j>=a[i].cost;j--)
                if(f[j]<f[j-a[i].cost]+a[i].val)
                    f[j]=f[j-a[i].cost]+a[i].val;
        printf("%d\n",f[v]);
    }
    return 0;
}
相關文章
相關標籤/搜索