题目链接: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]中。

附上源代码:

 #include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string>
#include<string.h>
#include<math.h>
#include<map>
#include<vector>
#include<algorithm>
using namespace std;
#define MAX 0x3f3f3f3f
#define MIN -0x3f3f3f3f
#define N 1005
int val[N];
int vol[N];
int dp[N][N];
int main()
{
int T;
int i, j;
int n, v;//物品,背包体积
scanf("%d", &T);
while (T--)
{
scanf("%d%d", &n, &v);
for (i = ; i <= n; i++)
scanf("%d", &val[i]);
for (i = ; i <= n; i++)
scanf("%d", &vol[i]);
memset(dp, , sizeof(dp));
for (i = ; i <= n; i++)
{
for (j = ; j <= v; j++)//体积可以是0
{
if (vol[i] <= j)//第i个物品的体积可以放到大小为j的背包中
dp[i][j] = max(dp[i - ][j], dp[i - ][j - vol[i]] + val[i]);//如果不放,前i-1件物品放入大小为v的包中。放的话,前i-1件物品放入v-vol[i]大的背包中
else
dp[i][j] = dp[i - ][j];//放不进去的话,相当于前i-1件物品放入大小为v的背包中
}
}
printf("%d\n", dp[n][v]);
}
return ;
}
顺便在附上错误的贪心代码,警告自己!
 #include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string>
#include<string.h>
#include<math.h>
#include<map>
#include<vector>
#include<algorithm>
using namespace std;
#define MAX 0x3f3f3f3f
#define MIN -0x3f3f3f3f
struct node
{
int volume;
int vaule;
double f;
}ans[];
int cmp(const void *a, const void *b)
{
struct node *aa = (node *)a;
struct node *bb = (node *)b;
return(((aa->f)<(bb->f)) ? : -);
}
int main()
{
int T;
int N, V;
int i;
int val;//价值
int vol;//体积
scanf("%d", &T);
while (T--)
{
scanf("%d%d", &N, &V);
for (i = ; i < N; i++)
{
scanf("%d", &ans[i].vaule);
}
for (i = ; i < N; i++)
{
scanf("%d", &ans[i].volume);
if (ans[i].volume == )
ans[i].f = MAX;
else
ans[i].f = ans[i].vaule*1.0 / ans[i].volume;
}
qsort(ans, N, sizeof(ans[]), cmp);
val = ;
vol = ;
ans[N].vaule = ;
ans[N].volume = ;
ans[N].f = ;
for (i = ; i <= N; i++)
{
if (vol <= V)
{
val = val + ans[i].vaule;
vol = vol + ans[i].volume;
}
else if (vol>V)
{
val = val - ans[i - ].vaule;
//vol = vol - ans[i - 1].volume;
//val = val + (V - vol)*(int)ans[i - 1].f;
break;
}
}
printf("%d\n", val);
}
return ;
}

ACM HDU Bone Collector 01背包的更多相关文章

  1. HDU 2602 Bone Collector(01背包裸题)

    Bone Collector Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) T ...

  2. HDU 2602 - Bone Collector - [01背包模板题]

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2602 Many years ago , in Teddy’s hometown there was a ...

  3. HDU 2602 Bone Collector --01背包

    这种01背包的裸题,本来是不想写解题报告的.但是鉴于还没写过背包的解题报告.于是来一发. 这个真的是裸的01背包. 代码: #include <iostream> #include < ...

  4. [HDU 2602]Bone Collector ( 0-1背包水题 )

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2602 水题啊水题 还给我WA了好多次 因为我在j<w[i]的时候状态没有下传.. #includ ...

  5. HDU 2602 Bone Collector (01背包DP)

    题意:给定一个体积,和一些物品的价值和体积,问你最大的价值. 析:最基础的01背包,dp[i] 表示体积 i 时最大价值. 代码如下: #pragma comment(linker, "/S ...

  6. Bone Collector(01背包+记忆化搜索)

    Bone Collector Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 32768/32768K (Java/Other) Tota ...

  7. hdoj 2620 Bone Collector(0-1背包)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2602 思路分析:该问题为经典的0-1背包问题:假设状态dp[i][v]表示前i件物品恰放入一个容量为v ...

  8. hdu2602 Bone Collector 01背包

    Many years ago , in Teddy’s hometown there was a man who was called “Bone Collector”. This man like ...

  9. [原]hdu2602 Bone Collector (01背包)

    本文出自:http://blog.csdn.net/svitter 题意:典型到不能再典型的01背包.给了我一遍AC的快感. //=================================== ...

随机推荐

  1. R学习笔记 第五篇:数据变换和清理

    在使用R的分组操作之前,首先要了解R语言包,包实质上是实现特定功能的,预先写好的代码库(library),R拥有大量的软件包,许多包都是由某一领域的专家编写的,但并不是所有的包都有很高的质量的,在使用 ...

  2. 五种js判断是否为整数(转)

    五种js判断是否为整数类型方式 作者:snandy 这篇文章主要介绍了五种JavaScript判断是否为整数类型方式,需要的朋友可以参考下   这篇看看如何判断为整数类型(Integer),JavaS ...

  3. Elasticsearch集群调优

    系统调优 禁用swap 使用swapoff命令可以暂时关闭swap.永久关闭需要编辑/etc/fstab,注释掉swap设备的挂载项. swapoff -a 如果完全关闭swap不可行,可以试着降低s ...

  4. 注销/etc/passwd带来的系统登陆不上

    今天在修改虚拟机密码上的时候,将/etc/passwd中root所在的哪行注销掉了,想象是注销了,root登陆时应该不要输入密码,结果是系统进度条走到最后的时候 进入不了系统了. 结果去普及了下/et ...

  5. c++学习笔记---05--- C++输出输入小结

    C++输出输入小结 题目: 这个程序将向用户提出一个"Y/N"问题,然后把用户输入的值赋值给answer变量. 要求: 针对用户输入'Y'或'y'和'N'或'n'进行过滤: 发掘程 ...

  6. vsftpd安装及虚拟用户配置

    服务器环境:CentOS6.9 Linux 2.6.32-696.10.1.el6.x86_64 安装vsftpd.db4.db4-utils # yum -y install vsftpd db4 ...

  7. php缓存模块apc可能导致php-fpm终止

    如果你的网站出现502错误.同时你网站中又使用了apc模块来做缓存处理.那么这篇文章兴许能帮到你. 首先,查看了php-fpm 的进程数. 发现php-fpm的进程数已经到达了php-fpm.conf ...

  8. unity下跨平台excel读写

    这是以前写的跨windows和ios读写excel的工具,因为原来导表工具引用的第三方读写excel的dll只能在windos下使用,造成要在mac机器上跑PC端或者打包的时候,每次都要先在windo ...

  9. 深入探讨List<>中的一个姿势。

    List<>是c#中很常见的一种集合形式,近期在阅读c#源码时,发现了一个很有意思的定义: [DebuggerTypeProxy(typeof(Mscorlib_CollectionDeb ...

  10. C#Session丢失问题的解决办法

    关于c# SESSION丢失问题解决办法   我们在用C#开发程序的时候经常会遇到Session很不稳定,老是数据丢失.下面就是Session数据丢失的解决办法希望对您有好处.1.在WEB.CONFI ...