zoukankan      html  css  js  c++  java
  • ACM HDU Bone Collector 01背包

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2602

    这是做的第一道01背包的题目。题目的大意是有n个物品,体积为v的背包。不断的放入物品,当然物品有各自的体积和价值。在不超过总体积v的情况下,问能够达到的最大价值。并且物品是一个一个放入的。最后若有剩余的体积也不会填满。

    刚开始是用贪心做的。将价值与体积的比值设定为一个值,即单位价值。然后按照单位价值排序,挨个取物品,考虑到了体积为0的情况,就将单位价值设定为无穷大。但是这样做并不能保证最优解。例如:总体积为5,一共有两个物品。第一个体积4,价值6。第二个体积为2,价值为4。很明显第一个更合适,但是按照单位价值比来做。结果就不是这样的了。所以贪心法不适合这样的01背包。但是适合物品可以只取一部分的01背包,是的最后的背包肯定会被刚好填满。

    在这道题中用数组dp来保存运算结果。例如dp[i][j]表示前i个物品放入体积为j的背包中。

    判断第i个物品能否放入大小为j的背包中。如果可以,是放?还是不放?
    重点是可以放的情况!

    最后需要注意的是体积可以为0,同时最后结果保存在dp[n][v]中。

    附上源代码:

     1 #include<iostream>
     2 #include<stdio.h>
     3 #include<stdlib.h>
     4 #include<string>
     5 #include<string.h>
     6 #include<math.h>
     7 #include<map>
     8 #include<vector>
     9 #include<algorithm>
    10 using namespace std;
    11 #define MAX 0x3f3f3f3f
    12 #define MIN -0x3f3f3f3f
    13 #define N 1005
    14 int val[N];
    15 int vol[N];
    16 int dp[N][N];
    17 int main()
    18 {
    19     int T;
    20     int i, j;
    21     int n, v;//物品,背包体积
    22     scanf("%d", &T);
    23     while (T--)
    24     {
    25         scanf("%d%d", &n, &v);
    26         for (i = 1; i <= n; i++)
    27             scanf("%d", &val[i]);
    28         for (i = 1; i <= n; i++)
    29             scanf("%d", &vol[i]);
    30         memset(dp, 0, sizeof(dp));
    31         for (i = 1; i <= n; i++)
    32         {
    33             for (j = 0; j <= v; j++)//体积可以是0
    34             {
    35                 if (vol[i] <= j)//第i个物品的体积可以放到大小为j的背包中
    36                     dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - vol[i]] + val[i]);//如果不放,前i-1件物品放入大小为v的包中。放的话,前i-1件物品放入v-vol[i]大的背包中
    37                 else
    38                     dp[i][j] = dp[i - 1][j];//放不进去的话,相当于前i-1件物品放入大小为v的背包中
    39             }
    40         }
    41         printf("%d
    ", dp[n][v]);
    42     }
    43     return 0;
    44 }
    View Code
    顺便在附上错误的贪心代码,警告自己!
     1 #include<iostream>
     2 #include<stdio.h>
     3 #include<stdlib.h>
     4 #include<string>
     5 #include<string.h>
     6 #include<math.h>
     7 #include<map>
     8 #include<vector>
     9 #include<algorithm>
    10 using namespace std;
    11 #define MAX 0x3f3f3f3f
    12 #define MIN -0x3f3f3f3f
    13 struct node
    14 {
    15     int volume;
    16     int vaule;
    17     double f;
    18 }ans[1005];
    19 int cmp(const void *a, const void *b)
    20 {
    21     struct node *aa = (node *)a;
    22     struct node *bb = (node *)b;
    23     return(((aa->f)<(bb->f)) ? 1 : -1);
    24 }
    25 int main()
    26 {
    27     int T;
    28     int N, V;
    29     int i;
    30     int val;//价值
    31     int vol;//体积
    32     scanf("%d", &T);
    33     while (T--)
    34     {
    35         scanf("%d%d", &N, &V);
    36         for (i = 0; i < N; i++)
    37         {
    38             scanf("%d", &ans[i].vaule);
    39         }
    40         for (i = 0; i < N; i++)
    41         {
    42             scanf("%d", &ans[i].volume);
    43             if (ans[i].volume == 0)
    44                 ans[i].f = MAX;
    45             else
    46                 ans[i].f = ans[i].vaule*1.0 / ans[i].volume;
    47         }
    48         qsort(ans, N, sizeof(ans[0]), cmp);
    49         val = 0;
    50         vol = 0;
    51         ans[N].vaule = 0;
    52         ans[N].volume = 0;
    53         ans[N].f = 0;
    54         for (i = 0; i <= N; i++)
    55         {
    56             if (vol <= V)
    57             {
    58                 val = val + ans[i].vaule;
    59                 vol = vol + ans[i].volume;
    60             }
    61             else if (vol>V)
    62             {
    63                 val = val - ans[i - 1].vaule;
    64                 //vol = vol - ans[i - 1].volume;
    65                 //val = val + (V - vol)*(int)ans[i - 1].f;
    66                 break;
    67             }
    68         }
    69         printf("%d
    ", val);
    70     }
    71     return 0;
    72 }
    View Code
  • 相关阅读:
    2014-11-27-0047-Java
    js去除数组中重复值
    一个数据表更新另外一个数据表(SQL)
    《js12种设计模式》
    《可编辑td》
    《JS 隔行换色》
    用Autohotkey让Kitty命令行变得更好用
    View epub and mobi File on Linux
    DrJava试用笔记
    Notes about BSD
  • 原文地址:https://www.cnblogs.com/lemonbiscuit/p/7776150.html
Copyright © 2011-2022 走看看