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;
}
相关文章
相关标签/搜索