Proud Merchants
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others)Total Submission(s): 1587 Accepted Submission(s): 633
Problem Description
Recently, iSea went to an ancient country. For such a long time, it was the most wealthy and powerful kingdom in the world. As a result, the people in this country are still very proud even if their nation hasn’t been so wealthy any more.
The merchants were the most typical, each of them only sold exactly one item, the price was Pi, but they would refuse to make a trade with you if your money were less than Qi, and iSea evaluated every item a value Vi.
If he had M units of money, what’s the maximum value iSea could get?
The merchants were the most typical, each of them only sold exactly one item, the price was Pi, but they would refuse to make a trade with you if your money were less than Qi, and iSea evaluated every item a value Vi.
If he had M units of money, what’s the maximum value iSea could get?
Input
There are several test cases in the input.
Each test case begin with two integers N, M (1 ≤ N ≤ 500, 1 ≤ M ≤ 5000), indicating the items’ number and the initial money.
Then N lines follow, each line contains three numbers Pi, Qi and Vi (1 ≤ Pi ≤ Qi ≤ 100, 1 ≤ Vi ≤ 1000), their meaning is in the description.
The input terminates by end of file marker.
Each test case begin with two integers N, M (1 ≤ N ≤ 500, 1 ≤ M ≤ 5000), indicating the items’ number and the initial money.
Then N lines follow, each line contains three numbers Pi, Qi and Vi (1 ≤ Pi ≤ Qi ≤ 100, 1 ≤ Vi ≤ 1000), their meaning is in the description.
The input terminates by end of file marker.
Output
For each test case, output one integer, indicating maximum value iSea could get.
Sample Input
2 10 10 15 10 5 10 5 3 10 5 10 5 3 5 6 2 7 3
Sample Output
5 11
Author
iSea @ WHU
Source
Recommend
zhouzeyong
思路:先将物品进行排序,再用01背包解决。
题意:有M的钱,要买N件商品中的一些,但每件商品在买之前要考察你的购买力Q是否满足,也就是你手上的钱够不够Q,但实际只花p的钱。如何买能得到最大价值。
令M=Q-P,即物品需要的购买力和实际花费的差。
结论:需要明白要想得到最大价值,必须考虑先买M大的物品。
对这个结论的证明,你可以假设有两件物品,且满足M1>M2,很容易证明
若先买第1件后,不能买第2件,则若先买第2件,一定不能买第1件。
所以考虑先买M大的物品看上去总是一种最优的选择方案。
然后只用对物品进行M的升序排列即可,若M相等,价值小的放到前面。
为什么要按升序,来源于此时考虑01背包时,物品总是先放入,再加上f[v-c[i]]的最大值。
贴上代码:
#include<stdio.h>
struct
{
int c;
int q;
int v;
}a[501];
int f[5001];
int main()
{
int i,j,n,m,v1,k,temp;
while(scanf("%d%d",&n,&m)!=EOF)
{
for(i=1;i<=n;i++)
scanf("%d%d%d",&a[i].c,&a[i].q,&a[i].v);
for(i=1;i<=m;i++)
f[i]=0;
for(i=1;i<n;i++)
{
k=i;
for(j=k+1;j<=n;j++)
{
if(a[k].q-a[k].c>a[j].q-a[j].c)
k=j;
else if(a[k].q-a[k].c==a[j].q-a[j].c)
{
if(a[k].v>a[j].v)
k=j;
}
}
if(k!=i)
{
temp=a[k].c;
a[k].c=a[i].c;
a[i].c=temp;
temp=a[k].q;
a[k].q=a[i].q;
a[i].q=temp;
temp=a[k].v;
a[k].v=a[i].v;
a[i].v=temp;
}
}
for(i=1;i<=n;i++)
{
for(v1=m;v1>=a[i].q;v1--)
{
j=f[v1-a[i].c]+a[i].v;
if(j>f[v1])
f[v1]=j;
}
}
printf("%d\n",f[m]);
}
return 0 ;
}
struct
{
int c;
int q;
int v;
}a[501];
int f[5001];
int main()
{
int i,j,n,m,v1,k,temp;
while(scanf("%d%d",&n,&m)!=EOF)
{
for(i=1;i<=n;i++)
scanf("%d%d%d",&a[i].c,&a[i].q,&a[i].v);
for(i=1;i<=m;i++)
f[i]=0;
for(i=1;i<n;i++)
{
k=i;
for(j=k+1;j<=n;j++)
{
if(a[k].q-a[k].c>a[j].q-a[j].c)
k=j;
else if(a[k].q-a[k].c==a[j].q-a[j].c)
{
if(a[k].v>a[j].v)
k=j;
}
}
if(k!=i)
{
temp=a[k].c;
a[k].c=a[i].c;
a[i].c=temp;
temp=a[k].q;
a[k].q=a[i].q;
a[i].q=temp;
temp=a[k].v;
a[k].v=a[i].v;
a[i].v=temp;
}
}
for(i=1;i<=n;i++)
{
for(v1=m;v1>=a[i].q;v1--)
{
j=f[v1-a[i].c]+a[i].v;
if(j>f[v1])
f[v1]=j;
}
}
printf("%d\n",f[m]);
}
return 0 ;
}