Codeforces Round #413:C. Fountains

本文介绍了一种在游戏内购中选择最优喷泉组合的方法,通过动态规划算法实现美观度最大化的同时确保玩家可以在金币和钻石两种货币限制下购买两个喷泉。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

C. Fountains
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

Arkady plays Gardenscapes a lot. Arkady wants to build two new fountains. There are n available fountains, for each fountain its beauty and cost are known. There are two types of money in the game: coins and diamonds, so each fountain cost can be either in coins or diamonds. No money changes between the types are allowed.

Help Arkady to find two fountains with maximum total beauty so that he can buy both at the same time.

Input

The first line contains three integers nc and d (2 ≤ n ≤ 100 0000 ≤ c, d ≤ 100 000) — the number of fountains, the number of coins and diamonds Arkady has.

The next n lines describe fountains. Each of these lines contain two integers bi and pi (1 ≤ bi, pi ≤ 100 000) — the beauty and the cost of the i-th fountain, and then a letter "C" or "D", describing in which type of money is the cost of fountain i: in coins or in diamonds, respectively.

Output

Print the maximum total beauty of exactly two fountains Arkady can build. If he can't build two fountains, print 0.

Examples
input
3 7 6
10 8 C
4 3 C
5 6 D
output
9
input
2 4 5
2 5 C
2 1 D
output
0
input
3 10 10
5 5 C
5 5 C
10 11 D
output
10


题意:

你有c枚金币,d枚钻石,现有n种不同的金币喷泉或钻石喷泉,它们价格不同,美观度也不同,你需要买下其中两个

(必须买两个,可以都是钻石喷泉或金币喷泉),问如何获得最大美观度,如果做不到输出0


模拟一遍就好,

先对喷泉按价格排序

dp[x][y]表示第x中货币(0表示金币,1表示钻石)价格不超过y可获得的最大美观度

遍历一遍所有喷泉,对于当前金币喷泉,最大美观度

ans = max(ans,当前喷泉美观度+dp[0][min(c-当前喷泉价格,前面所有喷泉中的最大价格)])

对于钻石喷泉同理,

最后别忘了可以钻石喷泉和金币喷泉各选一个,即dp[0][c]+dp[1][d]


#include<stdio.h>
#include<algorithm>
using namespace std;
#define LL long long
typedef struct Res
{
	LL val;
	LL p;
	bool operator < (const Res &b) const
	{
		if(p<b.p || p==b.p && val>b.val)
			return 1;
		return 0;
	}
}Res;
Res s[2][100005];
LL dp[2][100005];
int main(void)
{
	char ch;
	LL n, c, d, ka, kb, i, x, y, bet, ans, j, tt;
	scanf("%I64d%I64d%I64d", &n, &c, &d);
	ka = kb = ans = 0;
	for(i=1;i<=n;i++)
	{
		scanf("%I64d%I64d %c", &x, &y, &ch);
		if(ch=='C')
			s[0][++ka].val = x, s[0][ka].p = y;
		else
			s[1][++kb].val = x, s[1][kb].p = y;
	}
	sort(s[0]+1, s[0]+ka+1);
	sort(s[1]+1, s[1]+kb+1);
	//for(i=1;i<=ka;i++)  printf("%I64d %I64d\n", s[0][i].val, s[0][i].p);
	//for(i=1;i<=kb;i++)  printf("%I64d %I64d\n", s[1][i].val, s[1][i].p);
	bet = tt = 0;
	for(i=1;i<=ka;i++)
	{
		bet = max(bet, s[0][i].val);
		if(c>s[0][i].p && dp[0][min(c-s[0][i].p, tt)]>0)
			ans = max(ans, s[0][i].val+dp[0][min(c-s[0][i].p, tt)]);
		for(j=s[0][i-1].p;j<=s[0][i].p;j++)
			dp[0][j] = max(dp[0][j], dp[0][s[0][i-1].p]);
		dp[0][s[0][i].p] = max(dp[0][s[0][i].p], bet);
		tt = max(tt, s[0][i].p);
	}
	while(tt<=100000)
		dp[0][++tt] = dp[0][tt-1];
	bet = tt = 0;
	for(i=1;i<=kb;i++)
	{
		bet = max(bet, s[1][i].val);
		if(d>s[1][i].p && dp[1][min(d-s[1][i].p, tt)]>0)
			ans = max(ans, s[1][i].val+dp[1][min(d-s[1][i].p, tt)]);
		for(j=s[1][i-1].p;j<=s[1][i].p;j++)
			dp[1][j] = max(dp[1][j], dp[1][s[1][i-1].p]);
		dp[1][s[1][i].p] = max(dp[1][s[1][i].p], bet);
		tt = max(tt, s[1][i].p);
	}
	while(tt<=100000)
		dp[1][++tt] = dp[1][tt-1];
	if(dp[0][c]!=0 && dp[1][d]!=0)
		ans = max(ans, dp[0][c]+dp[1][d]);
	printf("%I64d\n", ans);
	return 0;
}
/*
2 12 1
5 4 C
5 2 C
*/


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值