点菜问题_1152

题目描述:

    北大网络实验室经常有活动需要叫外买,但是每次叫外买的报销经费的总额最大为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]。

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值