-
题目描述:
-
北大网络实验室经常有活动需要叫外买,但是每次叫外买的报销经费的总额最大为C元,有N种菜可以点,经过长时间的点菜,网络实验室对于每种菜i都有一个量化的评价分数(表示这个菜可口程度),为Vi,每种菜的价格为Pi, 问如何选择各种菜,使得在报销额度范围内能使点到的菜的总评价分数最大。
注意:由于需要营养多样化,每种菜只能点一次。
-
输入:
-
输入的第一行有两个整数C(1 <= C <= 1000)和N(1 <= N <= 100),C代表总共能够报销的额度,N>代表能点菜的数目。接下来的N行每行包括两个在1到100之间(包括1和100)的的整数,分别表示菜的>价格和菜的评价分数。
-
输出:
-
输出只包括一行,这一行只包含一个整数,表示在报销额度范围内,所点的菜得到的最大评价分数。
-
样例输入:
-
90 4 20 25 30 20 40 50 10 18 40 2 25 30 10 8
-
样例输出:
-
95 38
#include <stdio.h> #define INF 0xfffffff int dp[1001]; struct E { int value; int appraise; }menu[101]; int max(int x,int y) { return x>y?x:y; } int main() { /*思路: 0-1背包问题 核心公式:c[i][money]=max(c[i-1][money],c[i-1][money-price[i]]+value[i]) prince[i]:第i种菜的价格 value[i]:第i种菜的评价 c[i][money]:用j钱买第i种蔬菜的最大价值量 它等于两者中较大的一个: 1.买第i种菜,c[i-1][money-price[i]]+value[i] 2.不买第i种菜,c[i-1][money] */ int i,j,c,n; while(scanf("%d%d",&c,&n)!=EOF) //报销额度 菜品个数 { for(i=1;i<=n;i++) scanf("%d%d",&menu[i].value,&menu[i].appraise); for(i=0;i<=c;i++) dp[i]=0; for(i=1;i<=n;i++) { for(j=c;j>=menu[i].value;j--) dp[j]=max(dp[j],dp[j-menu[i].value]+menu[i].appraise); } printf("%d\n",dp[c]); } return 0; }
0,1背包问题
参考文章:http://love-oriented.com/pack/P01.html
http://www.cnblogs.com/tanky_woo/archive/2010/07/31/1789621.html
http://dongxicheng.org/structure/knapsack-problems/
优化空间参考:http://www.cnblogs.com/fly1988happy/archive/2011/12/13/2285377.html
-------------------------------
总结 :关键语句
f[i][v]=max{f[i-1][v],f[i-1][v-c[i]]+w[i]}
把这个过程理解下:在前i件物品放进容量v的背包时,
它有两种情况:
第一种是第i件不放进去,这时所得价值为:f[i-1][v]
第二种是第i件放进去,这时所得价值为:f[i-1][v-c[i]]+w[i]
(第二种是什么意思?就是如果第i件放进去,那么在容量v-c[i]里就要放进前i-1件物品【注:放得下,放得进的意思】)
最后比较第一种与第二种所得价值的大小,哪种相对大,f[i][v]的值就是哪种。
----------------------------------
有N件物品和一个容量为V的背包。第i件物品的费用是c[i],价值是w[i]。求解将哪些物品装入背包可使价值总和最大。
第i件物品的费用是c[i]---------------→要修改为:第i件物品的容量为c[i]
---------------------------------------------------
这个方程非常重要,基本上所有跟背包相关的问题的方程都是由它衍生出来的。所以有必要将它详细解释一下:“将前i件物品放入容量为v的背包中”这个子问题,若只考虑第i件物品的策略(放或不放),那么就可以转化为一个只牵扯前i-1件物品的问题。如果不放第i件物品,那么问题就转化为“前i-1件物品放入容量为v的背包中”,价值为f[i-1][v];如果放第i件物品,那么问题就转化为“前i-1件物品放入剩下的容量为v-c[i]的背包中”,此时能获得的最大价值就是f[i-1][v-c[i]]再加上通过放入第i件物品获得的价值w[i]。
---------------------------