点菜问题_1152

来源:互联网 发布:当代文学论文选题知乎 编辑:程序博客网 时间:2024/06/10 07:47
题目描述:

    北大网络实验室经常有活动需要叫外买,但是每次叫外买的报销经费的总额最大为C元,有N种菜可以点,经过长时间的点菜,网络实验室对于每种菜i都有一个量化的评价分数(表示这个菜可口程度),为Vi,每种菜的价格为Pi, 问如何选择各种菜,使得在报销额度范围内能使点到的菜的总评价分数最大。
    注意:由于需要营养多样化,每种菜只能点一次。

输入:

    输入的第一行有两个整数C(1 <= C <= 1000)和N(1 <= N <= 100),C代表总共能够报销的额度,N>代表能点菜的数目。接下来的N行每行包括两个在1到100之间(包括1和100)的的整数,分别表示菜的>价格和菜的评价分数。

输出:

    输出只包括一行,这一行只包含一个整数,表示在报销额度范围内,所点的菜得到的最大评价分数。

样例输入:
90 420 2530 2040 5010 1840 225 3010 8
样例输出:
9538
#include <stdio.h>#define INF 0xfffffffint 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]。

---------------------------

0 0
原创粉丝点击