遞歸:
int getNsumCount(int n, int sum)
{
if (n < 1 || sum < n || sum>6 * n)return 0;
if (n == 1)return 1;
int resCount = 0;
resCount = getNsumCount(n - 1, sum - 1) + getNsumCount(n - 1, sum - 2) + getNsumCount(n - 1, sum - 3) +
getNsumCount(n - 1, sum - 4) + getNsumCount(n - 1, sum - 5) + getNsumCount(n - 1, sum - 6);
return resCount;
}
動(dòng)態(tài)規(guī)劃
1.現(xiàn)在變量有:骰子個(gè)數(shù)扯饶,點(diǎn)數(shù)和恒削。當(dāng)有k個(gè)骰子,點(diǎn)數(shù)和為n時(shí)尾序,出現(xiàn)次數(shù)記為f(k,n)钓丰。那與k-1個(gè)骰子階段之間的關(guān)系是怎樣的?
2.當(dāng)有k-1個(gè)骰子時(shí)每币,再增加一個(gè)骰子携丁,這個(gè)骰子的點(diǎn)數(shù)只可能為1、2兰怠、3梦鉴、4李茫、5或6。那k個(gè)骰子得到點(diǎn)數(shù)和為n的情況有:
(k-1,n-1):第k個(gè)骰子投了點(diǎn)數(shù)1
(k-1,n-2):第k個(gè)骰子投了點(diǎn)數(shù)2
(k-1,n-3):第k個(gè)骰子投了點(diǎn)數(shù)3
....
(k-1,n-6):第k個(gè)骰子投了點(diǎn)數(shù)6
在k-1個(gè)骰子的基礎(chǔ)上尚揣,再增加一個(gè)骰子出現(xiàn)點(diǎn)數(shù)和為n的結(jié)果只有這6種情況涌矢!
所以:f(k,n)=f(k-1,n-1)+f(k-1,n-2)+f(k-1,n-3)+f(k-1,n-4)+f(k-1,n-5)+f(k-1,n-6)
3.有1個(gè)骰子掖举,f(1,1)=f(1,2)=f(1,3)=f(1,4)=f(1,5)=f(1,6)=1快骗。
遞歸函數(shù),返回和為n出現(xiàn)的次數(shù)塔次。所有的和出現(xiàn)次數(shù)總和為6^n方篮。
https://blog.csdn.net/k346k346/article/details/50988681
int getNsumCountnotRecusion(int n, int *count)
{
if (n < 1)return -1;
count[0] = count[1] = count[2] = count[3] = count[4] = count[5] = 1;
for (int i = 2; i <= n; i++)
{
for (int sum = 6 * i; sum >= i; sum--)
{
int tmp1 = ((sum - 1 - (i - 1)) >= 0 ? count[sum - 1 - (i - 1)] : 0);//兩個(gè)骰子不可能存在和為2的情況
int tmp2 = ((sum - 2 - (i - 1)) >= 0 ? count[sum - 2 - (i - 1)] : 0);//三個(gè)骰子不可能存在和為3的情況
int tmp3 = ((sum - 3 - (i - 1)) >= 0 ? count[sum - 3 - (i - 1)] : 0);//因此都減去了i-1
int tmp4 = ((sum - 4 - (i - 1)) >= 0 ? count[sum - 4 - (i - 1)] : 0);
int tmp5 = ((sum - 5 - (i - 1)) >= 0 ? count[sum - 5 - (i - 1)] : 0);
int tmp6 = ((sum - 6 - (i - 1)) >= 0 ? count[sum - 5 - (i - 1)] : 0);
count[sum - i] = tmp1 + tmp2 + tmp3 + tmp4 + tmp5 + tmp6;
}
}
return 0;
}