• 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需要比较长的时间。

    有个问题,有重复的吗?

     

  • 相关阅读:
    实用的网站记录
    XML记一次带命名空间的xml读取
    WEB项目挂载到IIS session过期
    【EF】CodeFirst Fluent API使用记录
    【Unity】微软的一款依赖注入组件
    【AutoFac】依赖注入和控制反转的使用
    【JavaScript】封装实用方法【持续积累】
    【Config】类库读取自己的配置文件,配置文件的扩展
    【c#】队列(Queue)和MSMQ(消息队列)的基础使用
    0、Java配置----JDK开发环境搭建及环境变量配置
  • 原文地址:https://www.cnblogs.com/Frandy/p/google_code_jam_pure_rank_python.html
Copyright © 2020-2023  润新知