hdu 3466 Proud Merchants(贪心+01背包)
2016-07-27 13:41
453 查看
题意:给你n件物品,每件物品需要花费pi价钱,它的价值为vi,并且每件物品能不能被买取决于你手里的钱是否大于每件物品的qi,你有m数量的钱,问最多的价值
分析:先按照q1-p1>q2-p2排序,然后01背包。大神说:
就是让C商品的q不等于p,其他都相同,这时,你就会发现如果要买C商品的话,肯定得先买C商品,因为买C商品的代价最大。所以,我们可以按照qi-pi的顺序来确定大顺序。这里我们还可以用更严谨的方式来证明一下,比如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大的先买。这里还得注意一点就是,排序的时候,得按照qi-pi从小到大排序,因为你买第n件商品的时候,是在比较你是否要先买第n件商品。打个比方让大家更好地理解,比如说f(3,
10),是不是max(f(2, 10-p3)+v3, f(2, 10)),你会发现这个第一种情况f(2,10-p3)+v3中,是先买了第三件商品,也就是说排在后面的商品会先买
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int dp[5555];
struct elem
{
int p,q,v;
} e[555];
bool cmp(elem a,elem b)
{
return (a.q-a.p)<(b.q-b.p);
}
int main()
{
int n,m;
while(~scanf("%d%d",&n,&m))
{
int i;
for(i=1;i<=n;i++)
{
scanf("%d%d%d",&e[i].p,&e[i].q,&e[i].v);
}
memset(dp,0,sizeof(dp));
sort(e+1,e+n+1,cmp);
int j;
for(i=1;i<=n;i++)
{
for(j=m;j>=e[i].q;j--)
{
dp[j]=max(dp[j],dp[j-e[i].p]+e[i].v);
}
}
//for(i=0;i<=m;i++) printf("%d\n",dp[i]);
printf("%d\n",dp[m]);
}
return 0;
}
分析:先按照q1-p1>q2-p2排序,然后01背包。大神说:
就是让C商品的q不等于p,其他都相同,这时,你就会发现如果要买C商品的话,肯定得先买C商品,因为买C商品的代价最大。所以,我们可以按照qi-pi的顺序来确定大顺序。这里我们还可以用更严谨的方式来证明一下,比如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大的先买。这里还得注意一点就是,排序的时候,得按照qi-pi从小到大排序,因为你买第n件商品的时候,是在比较你是否要先买第n件商品。打个比方让大家更好地理解,比如说f(3,
10),是不是max(f(2, 10-p3)+v3, f(2, 10)),你会发现这个第一种情况f(2,10-p3)+v3中,是先买了第三件商品,也就是说排在后面的商品会先买
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int dp[5555];
struct elem
{
int p,q,v;
} e[555];
bool cmp(elem a,elem b)
{
return (a.q-a.p)<(b.q-b.p);
}
int main()
{
int n,m;
while(~scanf("%d%d",&n,&m))
{
int i;
for(i=1;i<=n;i++)
{
scanf("%d%d%d",&e[i].p,&e[i].q,&e[i].v);
}
memset(dp,0,sizeof(dp));
sort(e+1,e+n+1,cmp);
int j;
for(i=1;i<=n;i++)
{
for(j=m;j>=e[i].q;j--)
{
dp[j]=max(dp[j],dp[j-e[i].p]+e[i].v);
}
}
//for(i=0;i<=m;i++) printf("%d\n",dp[i]);
printf("%d\n",dp[m]);
}
return 0;
}
相关文章推荐
- linux系统使用指令3
- 常见css样式
- javascript事件处理
- html--设置360浏览器默认为极速状态的mate标签
- 8天学通MongoDB——第七天 运维技术
- Ubuntu 下安装octave 4.0.3
- HDU 5761 Rower Bo(积分)
- @protocol和category 中如何使用@property (协议和分类中如何使用@property属性)
- MyBatis映射文件
- 【Android】【ViewGroup】【ListView】ListView的一些细节
- Mongodb主从复制
- PHP中的cURL函数
- 超赞!帮你打造极简风APP UI 的实用设计技巧
- Poll机制分析
- plsql远程连接oracle数据库
- 老百姓要看不起病!
- Javascript常用代码
- 8天学通MongoDB——第六天 分片技术
- 8天学通MongoDB——第五天 主从复制
- 调试存储过程时提示ORA-20000: ORU-10027: buffer overflow