TopCoder SRM 561 Div 2

博主分享了参加TopCoder SRM 561 Div 2比赛的经历,认为此次比赛难度较高,尤其500分题目未能解决。文章详细解析了250分题目的解题思路,涉及到城市游览的最大城市数量问题,强调注意天数恰好用完和数组越界的情况。同时,对500分/250分题目的气球分配问题进行了探讨,提出通过2^15的枚举结合题目排序来优化颜色更改次数的策略。

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

将近2个月没做TopCoder了,似乎官方都不给我发比赛提醒邮件了。。。这次的TopCoder好难,500分的题目最后都没做出来。。。

Div 2 250pt:

题意是给你一个可用天数total和一个去每个城市花费时间的数组d,求最多可以去多少个城市。

非常简单的一道题。容易忽略的地方有两个:一个是天数正好能被用完的情况,一个是数组越界。

Div 2 500 / Div 1 250:

题意是ICPC的比赛会给解决问题的队伍插气球。要求不同的题目的气球颜色必须不同,想吐题目的气球的尺寸必须相同。给你一个数组balloonCount代表你买的每种气球的个数,字符串balloonSize表示每种气球的大小,数组maxAccepted表示每个题目最多会有多少队伍能解决。问最少需要对多少气球改变颜色。

一开始一点想法都没有,后来看到maxAccepted的长度最多才15,因此想到可以2^15进行枚举哪道题用什么大小的气球。然而之后我就不知道该如何分配气球使得总的改变颜色次数最少。。。最后看了别人的代码才大概有了一点想法。。

首先把题目化简:假如没有大小限制,如何分配气球给不同的题目使得改变颜色最少?

这时,如果题目的数量比气球多,肯定无法完成分配。而如果气球多,则把 题目需求数 和 气球数 都排序,然后从 题目需求数 大的开始,需求最大 和 气球数最多的分配在一起。那么 改变颜色 的次数就是 当 需求数 大于 气球数 时的差值的和。

那么回到原来的问题,只需枚举每个题目使用的是 L 还是 M,那么就变成了两个 简单问题。最后求一个最小的答案即可。 代码如下:

class ICPCBallons {
	public int minRepaintings(int[] balloonCount, String balloonSize, int[] maxAccepted) {
		int numTasks = maxAccepted.length;
		int n = Math.max(balloonCount.length, numTasks);
		int[] larges = new int[n];
		int[] smalls = new int[n];
		int largsPtr = 0;
		int smallPtr = 0;
		for (int i = 0; i < balloonCount.length; ++i) {
			if (balloonSize.charAt(i) == 'L') {
				larges[largsPtr++] = balloonCount[i];
			} else {
				smalls[smallPtr++] = balloonCount[i];
			}
		}
		Arrays.sort(larges);
		Arrays.sort(smalls);
		Arrays.sort(maxAccepted);
		int res = (int) 1e9;
		for (int largeSet = 0; largeSet < (1 << numTasks); ++largeSet) {
			res = Math.min(res, minRepaint(larges, largeSet, maxAccepted, numTasks) + minRepaint(smalls, ((1 << numTasks) - 1) - largeSet, maxAccepted, numTasks));
		}
		if( res >= 1e9)
			return -1;
		return res;
	}
	private int minRepaint(int[] heaps, int set, int[] maxAccepted, int n) {
		int ptr = heaps.length - 1;
		int totalNegative = 0;
		int totalPositive = 0;
		for (int i = n-1; i >= 0; --i) {
			if (((set >> i) & 1) != 0) {
				int delta = heaps[ptr--] - maxAccepted[i];
				if (delta < 0) totalNegative += -delta; else totalPositive += delta;
			}
		}
		while (ptr >= 0) {
			totalPositive += heaps[ptr--];
		}
		if (totalPositive >= totalNegative) return totalNegative;
		return (int) 1e9;
	}
}


TopCoder的题目少,难度跨度大。。至今还在绿名。。。还要加油啊。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值