[Sword refers to offer] interview question 43: points of n dice, and the sword refers to offer
The first idea is that the number of points for each dice ranges from minimum to maximum. Suppose it is 1-6, then all the dice start from minimum 1. We assume a sort from left to right, the lowest value on the right, and the index starts from the lowest value.
def setTo1(dices, start, end):for i in range(start, end):dices[i] = 1def probability(n, s, dmax = 6, dmin = 1):if s < n * dmin or s > n * dmax : return 0dices = [1] * ni = n - 1total = 0while i >= 0:curSum = sum(dices)if curSum == s:print dicestotal += 1# find first one that can +1for j in range(i, -1, -1):if dices[j] < dmax and s - sum(dices[0:j+1]) >= n - j*dmin:dices[j] += 1setTo1(dices, j + 1, n)i = n - 1breakelse:i -= 1elif curSum < s:if dices[i] < dmax:dices[i] += 1i = n - 1else:i -= 1print "total = {0}, prob = {1}%".format(total, total*100/dmax**n)return total
If the current sum is less than s, it indicates whether the dice at the current index can be increased by 1. If yes, It is increased. Otherwise, you can check whether the dice before it can be increased. If they are equal, we need to change the current situation after statistics to handle the following situation. Because the index starts from low to current bit, we start from the current index, search for the dice that can be further increased. The judgment criterion here is that the number of current dice is smaller than the minimum value, and the minimum value of the subsequent dice should be 1, such as, 1, s = 6, the current index points to 4. Although the 4 here is smaller than the maximum number of points 6, if it is added, the third dice is 0, which does not meet the requirements. If you find the dice that you can add, add the dice points to 1, set all the dice to 1, index back to the end, and start to add again. For example, 1, 1, 6, s = 8, index pointing to 6, modified to 1, 2, 1, index pointing to the last 1 ,. If no dice can be added, it will end. For example, 6, 1, 1, s = 8.
In fact, if the given n is not big, we can set an n-bit integer, starting from n 1 and adding one after another to determine whether the sum of each bit meets the requirements until it reaches the maximum value, n 6.
In fact, dynamic planning has obvious characteristics.
'''@ state function: dp[i, j]: the total cases of sum = j, composed by i dices@ state tranfor function: dp[i, j] = sum(dp[i - 1, j - k]) for k in [dmin, dmax] @ dp[i, j] = 0, j > i * dmax or j < i * dmin@ init condition: dp[1, k] = 1, for k in [dmin, dmax], dp[1, k] = 0, for other k'''def dp_probability(n, s, dmax = 6, dmin = 1):if s < n * dmin or s > n * dmax : return 0dp1 = [0] * (n * dmax + 1)#init dp[1, :]for i in range(1, dmax + 1):dp1[i] = 1# i: the number of dicesfor i in range(2, n + 1):dp2 = [0] * (n * dmax + 1)# j: range of i dicesfor j in range(dmin * i, dmax * i + 1):# k: range of new added dice for k in range(dmin, dmax + 1):if j > k :dp2[j] += dp1[j - k]print dp2dp1 = dp2print "total = {0}, prob = {1}%".format(dp2[s], dp2[s]*100/dmax**n)return dp2[s]