zoukankan      html  css  js  c++  java
  • 03_01背包问题

    来源:刘汝佳《算法竞赛入门经典--训练指南》 P60 问题4:

    问题描述:有n种物品,每种只有一个,第i种物品的体积为Vi,重量为Wi。选一些物品装到一个容量为C的背包中,使得背包内物品在总体积不超过C的前提下重量尽量大。其中,1<=n<=100。1<=V<=C<=10000。1<=Wi<=10^6。

    分析:用f[i][j]表示“把前i个物品装到容量为j的背包中的最大总重量”,则状态转移方程为f[i][j] = Max{f[i-1][j],f[i-1][j-Vi]+Wi | Vi<=j};

    滚动数组优化后代码:

     1 memset(f,0,sizeof(f));
     2 for(int i=1; i<=n; i++)
     3 {
     4     scanf("%d %d",&V,&W);
     5     for(int j=C; j>=0; j--)
     6     {
     7         if(j>=V) 
     8             f[j] = Max(f[j],f[j-V]+W);
     9     }
    10 }

    例题来源:http://acm.hdu.edu.cn/showproblem.php?pid=2602

    例题:hdu 2602

    Bone Collector

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

    Problem 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

    题意:给一个体积为V( V <= 1000)的背包和n(n <= 1000 )个骨头,每个骨头i有各自的体积volume[i]和价格value[i],求在不超过背包体积V的前提下往背包里装骨头的最大价值。

    代码实现:

     1 #include "stdio.h"
     2 #include "string.h"
     3 #define N 1005
     4 int dp[N];
     5 int value[N];  //价值数组
     6 int volume[N]; //体积数组
     7 
     8 int Max(int a,int b) { return a>b?a:b; }
     9 
    10 int main()
    11 {
    12     int T;
    13     int n,V;  //n为骨头数量,V为背包体积
    14     int i,j,v,w;
    15     scanf("%d",&T);
    16     while(T--)
    17     {
    18         scanf("%d %d",&n,&V);
    19         memset(dp,0,sizeof(dp));
    20         for(i=0; i<n; i++)
    21             scanf("%d",&value[i]);
    22         for(i=0; i<n; i++)
    23             scanf("%d",&volume[i]);
    24         for(i=0; i<n; i++)
    25         {
    26             v = volume[i]; //第i个骨头的体积
    27             w = value[i]; //第i个骨头的价值
    28             for(j=V; j>=v; j--)
    29                 dp[j] = Max(dp[j],dp[j-v]+w);
    30         }
    31         printf("%d
    ",dp[V]);
    32     }
    33     return 0;
    34 }
  • 相关阅读:
    hdu 2082 找单词
    hdu 2079 选课时间(题目已修改,注意读题)
    hdu 2073 无限的路
    hdu 2062 Subset sequence
    poj 2777 Count Color
    hdu 2067 小兔的棋盘
    卡特兰数
    poj3468
    hdu1394
    hdu1166(线段树之单点更新)
  • 原文地址:https://www.cnblogs.com/ruo-yu/p/4384357.html
Copyright © 2011-2022 走看看