LintCoder python 小白2-骰子求和

题目:扔 n 个骰子,向上面的数字之和为 S。给定 Given n,请列出所有可能的 S 值及其相应的概率。

一开始的想法是:
投n个骰子,其实就是n次1-6的循环,将其每次和放在一个列表中,后面根据数字之和S范围(n,6n),用list.count(s[i])求出来每个情况下的次数之和,但是这样的话会导致内存超出限制,1-15个骰子还能够实现,后面基本不能。
一开始代码如下:

def sum1(x):
    count1=[]
    for i in x:
        for j in range(1,6+1):
                z=i+j
                count1.append(z)
    return count1

def dicesSum(self, n):
    # Write your code here
    if n==0 :
        return None
    if n==1:
        yy=[[1, 0.17], [2, 0.17], [3, 0.17], [4, 0.17], [5, 0.17], [6, 0.17]];
        return yy
    mylist=[1,2,3,4,5,6]
    for k in range(1,n):
        mylist=sum1(mylist);
    x=[]
    z1 = float(6**n)
    for z in range(n,6*n+1):
        result=mylist.count(z)   
        x=x+[[z,result/z1]] 
    return mylist

后面,找到网上一篇python这道题的代码,它通过动态规划,第一次开始累加到第n次骰子,其中发现到规律,n个骰子有5*n+1种s结果(6n-n+1),他们是对称情况,如果结果是偶数,则中间(5*n+1)/2和(5*n+1)/2+1是相同。

代码如下:

def dicesSum(self, n):
    # Write your code here
    if n == 0 : return None
    result = [
            [1,1,1,1,1,1],
            ]  #一开始第一个骰子出现的情况
        # if n == 1: return result[0]
        # 计算n个骰子出现的各个次数和
    for i in range(1,n):
        x = 5*(i+1)+1   #骰子从第二个开始出现取值可能的次数的情况有5n+1,这里n=i+1
        result.append([0 for _ in range(x)])  #重新一列后面补为0     
        for j in range(x):
            if j < 6:    #前六
                    result[i][j] = (sum(result[i-1][0:j+1]))
            elif j >=6 and j <= 3*i+2:  #六
                    result[i][j] = (sum(result[i-1][j-5:j+1]))#前面的n-1,
            else:
                break
        left = 0
        right = len(result[i]) - 1
        while left <= right:
            result[i][right] = result[i][left]
            left += 1
            right -= 1    #他们呈现对称

    res = result[-1]        #列表的倒数第一列
    all = float(sum(res))
    other = []
        # 第i个元素代表骰子总和为n+i
    for i,item in enumerate(res):  #额numerate遍历序列中的元素以及它们的下标
            # pro = self.round(item/all)
            # 自己写的四舍五入算法和LintCode有出入,其实网站自身会处理数据,这里不再做处理
        pro = item/all
        other.append([n+i,pro])
    return other

总结:
要考虑到内存和时间的限制
学会逆向思考,找到规律。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值