面試題60:n個骰子的點數
阿新 • • 發佈:2020-08-28
可以很輕鬆地想到用回溯法進行暴力列舉,但複雜度很高O(6^n),肯定會超時,所以可以類比為斐波那契數列的形式:\(f(n) = f(n-1)+f(n-2)+f(n-3)+f(n-4)+f(n-5)+f(n-6)\)。採用類似動態規劃的方法(其實和斐波那契一樣,並不嚴格是動態規劃)。
回溯法暴力列舉C++
int g_maxValue = 6; // 暴力遞迴,複雜度很高O(6^n),絕對超時 void Probability(int original, int current, int sum, int* pProbabilities){ if(current == 0){ pProbabilities[sum - original]++; return ; } for(int i = 1; i <= g_maxValue; ++i) Probability(original, current - 1, i + sum, pProbabilities); } void PrintProbability_Solution1(int number){ if(number < 1) return; int maxSum = number * g_maxValue; int* pProbabilities = new int[maxSum - number + 1]; for(int i = number; i <= maxSum; ++i) pProbabilities[i - number] = 0; Probability(number, number, 0, pProbabilities); int total = pow((double)g_maxValue, number); for(int i = number; i <= maxSum; ++i){ double ratio = (double)pProbabilities[i - number] / total; printf("%d: %e\n", i, ratio); } delete[] pProbabilities; } int main(int argc, char* argv[]){ PrintProbability_Solution1(6); return 0; }