动态规划之背包问题
Posted 小小范同学
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了动态规划之背包问题相关的知识,希望对你有一定的参考价值。
【原创】
在动态规划中有一个经典的问题,背包问题,一个背包体积为V,现有n件物品,每件物品都有其价值w和体积v,现在要求将物品装入背包,要求使其获得的价值最大,对这个问题,我们引入一个概念“性价比”,即价值和体积的比值w/v,表明单位体积的价值量,那么自然而然我们在选择物品时,一定是以此选择”性价比“大的物品,所以在数据处理时必须将物品按照“性价比”按照递减排序;下面来看一个题目描述
题目描述: 辰辰是个很有潜能、天资聪颖的孩子,他的梦想是称为世界上最伟大的医师。 为此,他想拜附近最有威望的医师为师。医师为了判断他的资质,给他出了一个难题。 医师把他带到个到处都是草药的山洞里对他说: “孩子,这个山洞里有一些不同的草药,采每一株都需要一些时间,每一株也有它自身的价值。 我会给你一段时间,在这段时间里,你可以采到一些草药。如果你是一个聪明的孩子,你应该可以让采到的草药的总价值最大。” 如果你是辰辰,你能完成这个任务吗? 输入: 输入的第一行有两个整数T(1 <= T <= 1000)和M(1 <= M <= 100),T代表总共能够用来采药的时间,M代表山洞里的草药的数目。 接下来的M行每行包括两个在1到100之间(包括1和100)的的整数,分别表示采摘某株草药的时间和这株草药的价值。 输出: 可能有多组测试数据,对于每组数据, 输出只包括一行,这一行只包含一个整数,表示在规定的时间内,可以采到的草药的最大总价值。 样例输入: 70 3 71 100 69 1 1 2
这里是采药问题,但是对比背包,这个问题是一样的变形,没有什么特殊之处,我们来看看代码:
#include <stdio.h> #include <stdlib.h> #include <algorithm> using namespace std; //0-1背包问题 struct bag{ int t; int v; double w; void set_w(){ w = (double)v/t; } bool operator < (const bag &A) const{//重载小于符号,使其能够排序; return w > A.w; } }bag_list[101]; void test_2() { int t,m; while( scanf("%d%d",&t,&m)!=EOF){ for (int i = 1; i<=m; i++) { scanf("%d%d",&bag_list[i].t,&bag_list[i].v); bag_list[i].set_w(); } // for (int i = 1; i<=m; i++) { // printf("%d %d %0.2f\n",bag_list[i].t,bag_list[i].v,bag_list[i].w); // } sort(bag_list+1, bag_list+m+1);//这个地方是m+1哦,如果下标是0开始,则是m // for (int i = 1; i<=m; i++) { // printf("%d %d %0.2f\n",bag_list[i].t,bag_list[i].v,bag_list[i].w); // } int ans = 0; for (int i =1; i<=m; i++) { if(bag_list[i].t<=t){ ans+=bag_list[i].v; t -= bag_list[i].t; } } printf("%d\n",ans); } } int main() { // test_1(); test_2(); return 0; }
这里使用了库函数,以及结构体中定义函数以及重载操作符的使用,sort是c++函数库中的函数,这个方法很方便,他对bag_list进行排序,之所以能够进行主要是因为bag中对<进行了重载,所以能够自动排序,如果没有重载,这里排序是有错误的;
以上是关于动态规划之背包问题的主要内容,如果未能解决你的问题,请参考以下文章