sise集训队背包测试C - Proud Merchants

C - Proud Merchants
Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u
Submit  Status

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? 

 

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. 

 

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
 

PS:

一开始没看清题意,以为是Q必须不大于M才能买,所以输入数据时直接过滤掉Q>M的数

测试的时候发现第二个数据错了,检查的时候才发现每买一件,M的值都会减少,不能只过滤掉Q>M的数然后直接dp

因为它有购买顺序问题

先来看看dp公式:

dp[k] = max(dp[k], dp[k - num[i].p] + num[i].v);
是从后面往前面找的,也就是后面的数选上了就是确定的,那么如果选了后面的数之后剩下的M变得很小,则接下来的商品能买的就变得很少,即使本来的钱是可以买这两件商品的,但现在变成只能买后面一件

举个例子:就用题目给的数据的第二个例子来说:

M=10

num[1].p = 5 num[1].q = 10  num[1].v = 5

num[2].p = 3 num[2].q = 5num[2].v = 6

num[3].p = 2 num[3].q = 7num[3].v = 3


如果按照这样的顺序,因为dp从后面开始

所以先买了num[3],之后M就剩下8

接下来再买了num[2], M就剩下5不够买num[1],次是价值为9

那我一开始不买num[3],先买num[2],M就剩下7,因为dp原因,它不会回去买num[3],只能向前买num[1],但是num[1]需要的Q>M,所以买不了,价值为6

由此可见,按这样的顺序能买到的最大价值为9


那如果颠倒过来,


M=10

num[1].p = 2 num[1].q = 7  num[1].v = 3

num[2].p = 3 num[2].q = 5num[2].v = 6

num[3].p = 5 num[3].q = 10num[3].v = 5

按上面那思路可以得出能买到的最大价值为11


再细看一下,不难得出,假使A为 p=3, q=5, v=6 B为p=5, q=10, v=5

如果先买A再买B,则需要pa+qb=13

如果先买B再买A,则需要pb+qa=10

我们肯定要选后者

那么就得出了商品排序要满足:pa+qb>pb+qa

交换位置得出:qa-pa<qb-pb


以下是AC代码:

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

int dp[5005];
struct M
{
	int p, q, v;
}num[505];

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

int main()
{
	int n, m;
	while (cin >> n >> m)
	{
		int j = 0;
		memset(dp, 0, sizeof(dp));
		for (int i = 0; i < n; ++i)
		{
			cin >> num[i].p >> num[i].q >> num[i].v;
			if (num[i].q > m)
			{
				i--;
				n--;
			}
		}
		sort(num, num + n, cmp);
		for (int i = 0; i < n; ++i)
		{
			for (int k = m; k >=num[i].q; --k)
			{
				dp[k] = max(dp[k], dp[k - num[i].p] + num[i].v);
			}
		}
		cout << dp[m] << endl;
	}

	return 0;
}

你可能感兴趣的:(sise集训队背包测试C - Proud Merchants)