google code jam exercise——Your Rank Is Pure
继续Round 1B 2010。第二道题没理解题目,第三道题题目可以理解,但是算法又折腾了好久。还是先看第三道题吧。
给定一个集合S={2,3,...n},它的子集S' 满足性质:n在S'中是第k个元素,那么k应该也在S'中,同样地,k是第k'个元素,那么k'应该也在S'中,经过有限步,k=1,不在S'中,称n对于S'是Pure Rank。那么给定一个n,求S'的个数。
在Content Analysis中,给除了动态规划算法的算法。我怎么觉得好多题都是动态规划,我正好不太懂态规划。看看具体算法如下,
如果n是一个集合S'的pure rank,S''=S' ^ {1,2,...k},那么k就是S''的pure rank。动态规划算法就是要找出从S''到S'的方法。
S'有k个元素,S''有k'个元素,那么从S'到S'',需要从{k+1,k+2,...n-1}中选k-k'个元素。
用count[n][k]表示有k个元素的,n为pure rank的集合S'的个数,那么就有count[n][k] = sum count[k][k']*C[n-k-1][k-k'-1] for k'=1...k-1
由于最后的数可能会比较大,在累加的过程中需要对100003取余。取余不能用一次大于等于100003就减掉的方法替代。
最后代码如下:
#!/usr/bin/python #encoding:UTF-8 #Filename:FileFixIt.py import sys def solveN(n): comb = [[0 for j in xrange(n+1)] for i in xrange(n+1)] j = 0 for i in xrange(n+1): comb[i][j] = 1 comb[i][i] = 1 for i in xrange(1,n+1): for j in xrange(1,i): comb[i][j] = comb[i-1][j]+comb[i-1][j-1] if comb[i][j]>=100003: comb[i][j] = comb[i][j]%100003 count = [[0 for j in xrange(n+1)] for i in xrange(n+1)] for i in xrange(2,n+1): count[i][1] = 1 for i in xrange(3,n+1): for j in xrange(2,i): count[i][j] = 0 for k in xrange(1,j): count[i][j] += count[j][k]* comb[i-j-1][j-k-1] if count[i][j]>=100003: count[i][j] = count[i][j]%100003 # print "count:" # for i in xrange(2,n+1): # for j in xrange(1,i): # print "count[%d][%d] %d" %(i,j,count[i][j]) # cnt = 0 # for j in xrange(1,n): # cnt += count[n][j] # print "cnt:",cnt # return cnt return count inname = "input.txt" outname = "output.txt" if len(sys.argv)>1: inname = sys.argv[1] outname = inname.rstrip(".in") outname = outname + ".out" fin = open(inname,"r") fout = open(outname,"w") testCaseNum = int(fin.readline().rstrip("\n")) caseNum = 0 lines = fin.readlines() allCase = [int(line.rstrip("\n")) for line in lines] maxN = max(allCase) count = solveN(maxN) for caseNum,n in enumerate(allCase): cnt = 0 for j in xrange(1,n): cnt += count[n][j] if cnt>=100003: cnt = cnt%100003 answer = "Case #%d: %d\n" %(caseNum+1,cnt) fout.write(answer) fin.close() fout.close()
最后small和large case测试都通过了,large case需要比较长的时间。
有个问题,有重复的吗?