TopCoder SRM305 DIV1 Report
match date:Wednesday, May 31, 2006
report date:Sunday, June 4, 2006
看题不仔细,算法不扎实,总之仍需再虚心学习学习再学习。
Problem 250 - UnfairDivision :
Problem 900 - PowerCollector :
Problem 250 - UnfairDivision :
带小陷阱的模拟题,A B C三人分财产,需要对n份财产划两刀,按规则拿取各自的一份。规则是A划第一刀,B划第二刀、C选第一份、B选第二份、最后的给A。因为B对A有偏见,所以当B有两种选择可以拿到相同的数目财产时,B会选择给C多一点的情况。
对A的划分先枚举,其中取值最大的情况。在每一个A的枚举中需要对B的划分再枚举,按题意,保持B的财产最多和C的最多的情况。
最后A的最大值就是结果。
Problem 500 - InterleavePal :
是一道典型的动规,不过要是没想到动规可就不太好做了。原本以为是字符串的处理这一类的,但在看过解题报告后才知道,这是一道思路很清晰的动规。
用boolean值数组dp[A][B][C][D]表示第一个String的子串A到B和第二个String的子串C到D经过合并后可以得到回文。其回文长度自然是B-A+D-C。
对于比dp[A][B][C][D]长的回文可以通过四种扩展获得,即 dp[A-1][B+1][C][D],dp[A-1][B][C][D+1],dp[A][B+1][C-1][D],dp[A][B][C-1][D+1],都需要保证扩展的两个字符是相等的,否则扩展出来的就不是回文了。
所以通过以上的解题思路,再维护一个max值表示最长的回文,就行了。
Problem 900 - PowerCollector :
考虑n^k,若k=a*b (a<b ),则对应n^k有(n^a)^b和(n^b)^a,在计算时出现了重复。为了解决重复的问题,首先保证幂是质数,这样就能消除n^k的情况,然后在(n1)^b和(n2)^a相等的情况下取k大这,按上例是取(n1)^b (n1=n^a)。
由于指数的范围较小,所以判断质数只要一个简单的循环即可。
boolean isPrime(int k) {
for (int i = 2; i < k; i++) {
if (k % i == 0)
return false;
}
return true;
}
设func(n,k)表示 a^b<=n (b<k) 的a^b值的个数,比如此题就可以说是在求func(n,log2(n))。 对于每个指定的b(保证b是质数),a^b的个数就是a的个数,所以求n^(1/b)(安全一点的可以用二分法查找最大的a)得到a就是个数r。而为了减去上面提到的k比较小的情况,需要将r减去func(a,b)。
long func(long n, int k) {
long cnt = 1;
for (int b = 2; b < k; b++) {
if (!isPrime(b))
continue;
long r = Math.pow(n,1.0/ b);
if (r == 1)
break;
cnt += r - func(r, b);
}
return cnt;
}
My Blog:
http://blog.csdn.net/ray58750034/
My statistic:
http://www.topcoder.com/stat?c=coder_room_stats&rd=9826&cr=20862220
SRM 301 - Problem Set & Analysis:
http://www.topcoder.com/tc?module=Static&d1=match_editorials&d2=srm305