[hdu3466]Proud Merchants

题目链接

思考

首先这道题目我WA了很多次,在没有思路的情况下去偷偷看了一下题解。题解中关键的一步 按照Q-P从小到大排序 让我十分不解,为什么会有这种操作。

而且很多博客,只说为了无后效性之类的,完全没有解释清除(可能大佬们不屑于对这种题目多费口舌)。作为一只小蒟蒻,在翻阅了很多博客与思考之后。

想到:

设A:p1 q1, B:p2 q2,然后,假设单独买A或者B的话,都是可以买到的。这时,若先买A,则你至少需要p1+q2的钱;若先买B,则至少需要p2+q1的钱。那肯定是花最少的钱咯,所以如果先买A再买B,那么p1+q2<p2+q1,转换一下,就是q1-p1>q2-p2,也就是说qi-pi大的先买。这是暴力思考的想法。

但是DP的递推是与暴力顺序完全是相反的举个例子。

3 10

P  Q  V

5 10 5  物品1

3 5 6   物品2

2 7 3   物品3

Q-P中最大的是 5 10 5,如果暴力算法的话 从物品1(选)->物品3(不选)->物品2 (选) 最大价值11

但是DP的话 就得从 限制最小的 物品2  -> 物品3  -> 物品1 最大价值11

 109876543210
物品150000000000
物品333330000000
物品296666600000

 

 

 

 

#include <cstdio>
#include <cstring>
#include <algorithm>
int n,m,dp[5500],MAX=0;
struct node{
    int P,Q,V;
}good[550];
bool CMP(node a,node b){
    return (a.Q-a.P) < (b.Q-b.P);
}
int main(){
    while( scanf("%d%d",&n,&m) != EOF ){
        for(register int i=1;i<=n;i++){
        scanf("%d%d%d",&good[i].P,&good[i].Q,&good[i].V);
        }
        memset(dp,0,sizeof(dp));
        std::sort(good+1,good+1+n,CMP);
        for(register int i=1;i<=n;i++)    
            for(register int j=m;j>=good[i].Q;j--){
                    dp[j] = std::max(dp[j],dp[j-good[i].P]+good[i].V);
            }
        printf("%d\n",dp[m]);
    }
    return 0;
}
代码实现

 

转载于:https://www.cnblogs.com/OIerLYF/p/6937607.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值