TopCoder SRM 561 Div 2

来源:互联网 发布:倍投软件 编辑:程序博客网 时间:2024/05/12 14:39

将近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的题目少,难度跨度大。。至今还在绿名。。。还要加油啊。。。