SRM539-div1-1-div2-2-Over9000Rocks
2012-04-08 21:27
260 查看
zz:
http://www.strongczq.com/2012/04/srm539-div1-1-div2-2-over9000rocks.html
题目原文:http://community.topcoder.com/stat?c=problem_statement&pm=11855
[align=left]
[/align]
[align=left]题目大意:[/align]
[align=left] 从若干个盒子中任意选择几个装石头,每个盒子容量都有上下限,一旦选择使用某个盒子,那么填装的石头数必须在该盒子的上下限容量之间。假设最终填装的石头总数为X,那么符合条件X>9000的X有多少个?[/align]
[align=left] 数据规模:盒子总数[1,15], 盒子容量[1,10^6][/align]
[align=left]
[/align]
[align=left]思路:[/align]
[align=left] 由于盒子数的最大值只有15,所以可以遍历所有的盒子选择方案,总共2^15=32K种。在每一种选择方案中,累加所有盒子的容量下限和上限作为总的容量下限和上限(下限要与9001取最大值),总容量下限都上限之间的所有值都是X的可能值。汇总所有方案下的所有取值(需要去重)就可以得到最终结果。[/align]
[align=left] 由于每种方案下的取值区间最小值都可以达到接近10^6,所以一个个记录可能取值肯定会超时的(2^15*10^6)。好在我们只需要记录每中方案下的取值范围起始值和终止值便可。最终根据这些记录的范围来计算所有可能取值数。有两种实现方式(假设盒子数为k):[/align]
保存每种方案下的取值范围二元组[s,t],总共有2^k。对这些二元组进行从小到大排序,二元组中s为主键,t为第二主键。然后从小到大扫描这些二元组,过程中保留目前所遇到的X可行取值的最大值lastMax。对于当前二元组[s,t],分别比较s、t与lastMax的大小关系去除重复的取值,将新发现的取值范围的长度加到最终结果中,然后更新lastMax。
利用一个大小为15×10^6+2的数组short[] bound保存各方案下的取值范围,假设某个方案的取值范围是[s,t],则bound[s]++, bound[t+1]--。然后遍历从9001到15×10^6的每个值x,考虑bound[9001]+bound[9002]+...+bound[x]的取值,如果大于0则说明x处于某个取值范围中,否则不是。(该数组的大小可以优化为所有盒子容量上限的加和)。
第二种方法在最坏情况下空间和时间消耗都更大,但是编码更简单些,以下代码使用第二种实现方式。
Java代码:
http://www.strongczq.com/2012/04/srm539-div1-1-div2-2-over9000rocks.html
题目原文:http://community.topcoder.com/stat?c=problem_statement&pm=11855
[align=left]
[/align]
[align=left]题目大意:[/align]
[align=left] 从若干个盒子中任意选择几个装石头,每个盒子容量都有上下限,一旦选择使用某个盒子,那么填装的石头数必须在该盒子的上下限容量之间。假设最终填装的石头总数为X,那么符合条件X>9000的X有多少个?[/align]
[align=left] 数据规模:盒子总数[1,15], 盒子容量[1,10^6][/align]
[align=left]
[/align]
[align=left]思路:[/align]
[align=left] 由于盒子数的最大值只有15,所以可以遍历所有的盒子选择方案,总共2^15=32K种。在每一种选择方案中,累加所有盒子的容量下限和上限作为总的容量下限和上限(下限要与9001取最大值),总容量下限都上限之间的所有值都是X的可能值。汇总所有方案下的所有取值(需要去重)就可以得到最终结果。[/align]
[align=left] 由于每种方案下的取值区间最小值都可以达到接近10^6,所以一个个记录可能取值肯定会超时的(2^15*10^6)。好在我们只需要记录每中方案下的取值范围起始值和终止值便可。最终根据这些记录的范围来计算所有可能取值数。有两种实现方式(假设盒子数为k):[/align]
保存每种方案下的取值范围二元组[s,t],总共有2^k。对这些二元组进行从小到大排序,二元组中s为主键,t为第二主键。然后从小到大扫描这些二元组,过程中保留目前所遇到的X可行取值的最大值lastMax。对于当前二元组[s,t],分别比较s、t与lastMax的大小关系去除重复的取值,将新发现的取值范围的长度加到最终结果中,然后更新lastMax。
利用一个大小为15×10^6+2的数组short[] bound保存各方案下的取值范围,假设某个方案的取值范围是[s,t],则bound[s]++, bound[t+1]--。然后遍历从9001到15×10^6的每个值x,考虑bound[9001]+bound[9002]+...+bound[x]的取值,如果大于0则说明x处于某个取值范围中,否则不是。(该数组的大小可以优化为所有盒子容量上限的加和)。
第二种方法在最坏情况下空间和时间消耗都更大,但是编码更简单些,以下代码使用第二种实现方式。
Java代码:
public class Over9000Rocks { public int countPossibilities( int[] lowerBound, int[] upperBound) { int n = lowerBound.length ; int maxRes = 0; for (int i = 0; i < n; ++i){ maxRes += upperBound[i]; } int [] bound = new int[maxRes + 2]; for (int m = 1; m < (1 << n); ++m) { int low = 0, up = 0; for (int i = 0; i < n; ++i) { if ((m & (1 << i)) > 0) { low += lowerBound[i]; up += upperBound[i]; } } low = Math. max(low, 9001); if (up < low) { continue ; } bound[low]++; bound[up + 1]--; } int res = 0; int v = 0; for (int x = 9001; x <= maxRes; ++x){ if ((v += bound[x]) > 0){ res++; } } return res; } }
相关文章推荐
- SRM539-div2-3-CaptureFish
- srm539 div1
- SRM574 Div1 450
- topcoder-srm-233-div2
- SRM 606 div2 500 EllysNumberGuessing
- topcoder SRM 637 DIV2题解
- SRM 559 Div1 500 HatRack
- 拓扑排序 SRM 660 Div2 Medium: PrivateD2party
- SRM 584 DIV1
- 【TopCoder】SRM160 DIV1总结
- 有向图判环+拆解图求参会期望 SRM 660 Div1 Medium: Privateparty
- TopCoder SRM 609 Div1 第2题
- SRM 628 DIV2 1000 CandleTimerEasy 状态压缩+DFS
- topcoder srm 699 div1 -3
- Topcoder SRM 687 (Div 2) 500.Quacking __ string matches
- SRM 501 DIV2悲剧
- topcoder srm 690 div1 -3
- Topcoder SRM 687 div2
- [LP对偶费用流] SRM 676 div1 Farmville
- TopCoder SRM 663 Div2 Problem 1000 - CheeseRolling (状压dp)