HDU-3466-Proud Merchants

题目链接

http://acm.hdu.edu.cn/showproblem.php?pid=3466

这题是个好题,之前没有想到得按先q-p来排序,因为q的原因,取得顺序不好就得不到最大价值。

看了OceanLight     http://blog.csdn.net/oceanlight/article/details/7866759#comments  的博客

题意是: 给你一些钱 m ,然后在这个国家买东西, 共有 n 件物品,每件物品有  价格 P    价值 V    还有一个很特别的属性 Q, Q 指 你如过想买这件物品 你的手中至少有这钱Q 。 虽然你只要花费 钱P ,但你的手中至少有钱Q,如果不足Q ,不能买。问给你钱M ,列出N件物品,最多能获得多少价值的东西。。。。

第一眼看是个DP。。。。  但是想了许久都想不出   状态转移方程。。。

废话不多说。 给出解题思路。。。。。

解:    按 Q-P 的大小 ,从小到大排序,然后按照0-1 背包的思想

dp[c]=max(dp[c],dp[c-p[i]])+v[i];  最终 dp[m]就是结果。

思路很简单,但是很难想。

在这我给出为什么要按Q-P排序的证明

一。 首先,不想为什么 ,要按照Q-P  排序。我们先想这么一个问题,(原因一会就知道了)。

   给你n 个这种商品,你最少需要多少钱能够买下来。。(通过这个问题,可以找出一个性质)

再把这个商品转化 一下。。

还是有三个属性  P 价格 、V 价值 、 M 为Q-P

Sum = P1 +P2 +P3 +........+Pn+max(Mi-(P(i+1)+P(i+2)+...........Pn));

要使得Sum 最小 就应该按照 M从大到小排序 (这里就是从大到小,没错),然后0-1背包求解。

证明:

如果看不懂公式 是什么 意思。。。没关系    那你就看 这样一个题的题解。。。这里有相同的公式(很简单的)

http://blog.csdn.net/oceanlight/article/details/7862104

这是我昨天写的一个题的题解,真没想到今天会用到的。。。

如果你看完了,你就应该懂了 。 要得到最小的sum ,就应该按照  M 从大到小排序了吧

也就是说我们应该先买M最大的物体,然后买M第二大的 。。。。。  最后买最小的。。。这个性质是这个问题的关键。

二。给一定的钱 ,我们的购买方式是  应该先买M最大的物体(M=Q-P),然后依次买第二大、第三大、、、、、

我们已经知道这个购买方式,怎么实现就要用到DP  中的0-1背包的思想了。

dp[c]=max(dp[c],dp[c-p[i]])+v[i];   c 为第c 个物品。这是用一维数组实现01背包。。

dp[c-p[i]] 是指   我们在容量为c 的包中 放了p[i]之后  还能放的物品的价值。

i 从 1 到 n  。 dp[c-p[n]]  是放了 第n个物品后 还能放多少价值的物品。。。所以  P[n] 的M 值应该最大

通俗的说: 这个dp过程 正好是逆向的  。   dp[c-p[i]]是dp[c]的最优子结构。

所以 在DP 的时候我们应该按照 M的值从小到大排序。

也就是说我们应该按照 Q-P 的值 从小到 大排序在 DP 了。。。。

觉得对dp的理解深刻了一点,又感觉对dp不怎么理解了,

代码

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;

struct node
{
int p,q,v;
}me[505];

bool cmp(node a,node b)
{
return a.q-a.p<b.q-b.p;
}

int main(void)
{
int i,j,k,n,m;
int dp[5005];
while(scanf("%d%d",&n,&m)==2)
{
memset(dp,0,sizeof(dp));
for(i=0;i<n;i++)
scanf("%d%d%d",&me[i].p,&me[i].q,&me[i].v);
sort(me,me+n,cmp);
for(i=0;i<n;i++)
{
for(j=m;j>=me[i].q;j--)
{
dp[j]=max(dp[j],dp[j-me[i].p]+me[i].v);
}
}
printf("%d\n",dp[m]);
}
return 0;
}

参数
62MS 368K 680 B

时间: 2025-01-04 12:15:11

HDU-3466-Proud Merchants的相关文章

hdu 3466 Proud Merchants(0-1背包+排序)

题目来源:hdu 3466 Proud Merchants Proud Merchants Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others) Total Submission(s): 3595 Accepted Submission(s): 1500 Problem Description Recently, iSea went to an ancient country. For

hdu 3466 Proud Merchants(有排序的01背包)

Proud Merchants Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others)Total Submission(s): 4039    Accepted Submission(s): 1677 Problem Description Recently, iSea went to an ancient country. For such a long time, it was

HDU 3466 Proud Merchants(01背包)

这道题目看出背包很容易,主要是处理背包的时候需要按照q-p排序然后进行背包. 这样保证了尽量多的利用空间. Proud Merchants Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others) Total Submission(s): 2674    Accepted Submission(s): 1109 Problem Description Recently, iSea we

hdu 3466 Proud Merchants &lt;背包+sort排序&gt;

Proud Merchants Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others) Total Submission(s): 3616    Accepted Submission(s): 1511 Problem Description Recently, iSea went to an ancient country. For such a long time, it was

HDU 3466 Proud Merchants(0-1背包)

http://acm.hdu.edu.cn/showproblem.php?pid=3466 题意: 最近,iSea去了一个古老的国家.在这么长的时间里,它是世界上最富有和最强大的王国.结果,这个国家的人民仍然非常自豪,即使他们的国家没有那么富有了.商人是最典型的,每个人只卖一个项目,价格是Pi,但如果你的钱少于Qi,他们会拒绝与你交易,iSea评估每个项目一个值Vi.如果他有M单位的钱,iSea可以获得的最大价值是多少? 思路: 这道题的话多加了一个Qi. 一定要注意,若要保证动归方程无后效性

hdu 3466 Proud Merchants 自豪的商人(01背包,微变形)

题意: 要买一些东西,每件东西有价格和价值,但是买得到的前提是身上的钱要比该东西价格多出一定的量,否则不卖.给出身上的钱和所有东西的3个属性,求最大总价值. 思路: 1)WA思路:与01背包差不多,dp过程中记录每个容量所能获得的最大价值以及剩余的容量.实现是,开个二维dp数组,从左往右扫,考虑背包容量为j的可获得价值量,根据该剩余容量得知要更新后面哪个背包容量[j+?] ,如果剩余容量大于q[i]那么可以直接装进去,更新价值以及剩余容量,否则,考虑更新的是更大的背包容量.这个思路有缺陷,一直找

hdu 3466 Proud Merchants 【限制性01背包】

题目链接:https://vjudge.net/contest/103424#problem/J 转载于:https://www.bbsmax.com/A/RnJW16GRdq/ 题目大意: 有n个商品m块钱,给出买每个商品所花费的钱P.钱包里需要至少Q才有资格买.商品的价值V.问你如何购买商品的价值最大. 解题分析:考虑下面的例子:A:p1=5, q1=10, v1=5; B:p2=3, q2=5, v2=6; 如果先买物品A再买物品B的话我至少需要10元钱,也就是money >= p1+q2

【HDOJ】3466 Proud Merchants

先排序预处理,后01背包. 1 #include <stdio.h> 2 #include <string.h> 3 #include <stdlib.h> 4 5 #define MAX(a, b) (a>b) ? a:b 6 7 int dp[5000]; 8 9 typedef struct { 10 int p, q, v; 11 } stuff_st; 12 13 stuff_st stuffs[505]; 14 15 int comp(const vo

01背包水题篇之HDU3466——Proud Merchants

这是个好题,菜鸟刚学dp,这题把我以前的想法全都给完完全全的颠覆了.其实是自己没了解无后效性的概念. 然后我去开开心心滴跑去问队长:"队长,队长,怎么理解动归的无后效性啊???" 学长很深沉滴对我说:"做多了就会了" "噢噢"(好吧) 然后学长又补了句:"能构成有向无环图的都能用DP搞." 我心里想:"队长就知道搞妹~~~." 默默去翻小白书看看DAG去了. 为了搞清楚这题怎么写,操了度娘千百遍,还是没搞定

HDU3466 Proud Merchants[背包DP 条件限制]

Proud Merchants Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others)Total Submission(s): 5599    Accepted Submission(s): 2362 Problem Description Recently, iSea went to an ancient country. For such a long time, it was