博客
关于我
ACM HDU Bone Collector 01背包
阅读量:444 次
发布时间:2019-03-06

本文共 2780 字,大约阅读时间需要 9 分钟。

题目链接:

这是做的第一道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
2 #include
3 #include
4 #include
5 #include
6 #include
7 #include
8 #include
9 #include
10 using namespace std;11 #define MAX 0x3f3f3f3f12 #define MIN -0x3f3f3f3f13 #define N 100514 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++)//体积可以是034 {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 else38 dp[i][j] = dp[i - 1][j];//放不进去的话,相当于前i-1件物品放入大小为v的背包中39 }40 }41 printf("%d\n", dp[n][v]);42 }43 return 0;44 }
View Code
顺便在附上错误的贪心代码,警告自己!
1 #include
2 #include
3 #include
4 #include
5 #include
6 #include
7 #include
8 #include
9 #include
10 using namespace std;11 #define MAX 0x3f3f3f3f12 #define MIN -0x3f3f3f3f13 struct node14 {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 else46 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\n", val);70 }71 return 0;72 }
View Code

转载地址:http://aojyz.baihongyu.com/

你可能感兴趣的文章
mysql_secure_installation初始化数据库报Access denied
查看>>
MySQL_西安11月销售昨日未上架的产品_20161212
查看>>
Mysql——深入浅出InnoDB底层原理
查看>>
MySQL“被动”性能优化汇总
查看>>
MySQL、HBase 和 Elasticsearch:特点与区别详解
查看>>
MySQL、Redis高频面试题汇总
查看>>
MYSQL、SQL Server、Oracle数据库排序空值null问题及其解决办法
查看>>
mysql一个字段为空时使用另一个字段排序
查看>>
MySQL一个表A中多个字段关联了表B的ID,如何关联查询?
查看>>
MYSQL一直显示正在启动
查看>>
MySQL一站到底!华为首发MySQL进阶宝典,基础+优化+源码+架构+实战五飞
查看>>
MySQL万字总结!超详细!
查看>>
Mysql下载以及安装(新手入门,超详细)
查看>>
MySQL不会性能调优?看看这份清华架构师编写的MySQL性能优化手册吧
查看>>
MySQL不同字符集及排序规则详解:业务场景下的最佳选
查看>>
Mysql不同官方版本对比
查看>>
MySQL与Informix数据库中的同义表创建:深入解析与比较
查看>>
mysql与mem_细说 MySQL 之 MEM_ROOT
查看>>
MySQL与Oracle的数据迁移注意事项,另附转换工具链接
查看>>
mysql丢失更新问题
查看>>