演算法回憶錄:母函式解決整數拆分
阿新 • • 發佈:2019-01-27
省略了很多內容,所以需要一定基礎才可閱讀。主要為了說清母函式如何解決此問題。
整數拆分:
1、整數拆分可以理解為蘋果放盤子問題(把N個蘋果放在M個盤子裡有多少種方法),只是這是相當於把N個蘋果放在N個盤子裡而已。
程式碼:
int zh(int n,int m)
{
if(n==1 || m==1)
return 1;
if(n <= m)
return (1 + zh(n, n-1));
return zh(n, m-1) + zh(n-m, m);
}
2、整數拆分同樣可以用遞推解決,其實這同樣用到了遞迴所得的關鍵函式關係: f(n, m) = f(n, m-1) + f(n-m, m)。
for(int i=1; i<=n; i++) {
for(int j=1; j<=n;j ++){
if(i <= j){
ans[j] += ans[j-i];
}
}
}
3、用母函式解決: 這才是本文的關鍵。
a、首先要理解為什麼整數拆分可以用G(x)=(1+x+x^2+x^3+x^4+……)(1+x^2+x^4+x^6)
b、如何理解程式碼? 迴圈的控制很難理解:但是大體可以這樣解釋:顯然c1儲存變數,c2為臨時變數;執行一次i迴圈,c2則表示乘到當前多項式x的n次冪的係數為c2【n】,然後c2賦值到c1,c2初始化,繼續執行。
while (cin>>n) {
for (i=0; i<=n; i++) { c1[i]=0; c2[i]=0; }
for (i=0; i<=n; i++) c1[i]=1;
for (i=2; i<=n; i++) {
//key code
for (j=0; j<=n; j++) {
for (k=0; k+j<=n; k+=i) {
c2[j+k] += c1[j];
}
}
for (j=0; j<=n; j++) {
c1[j] = c2[j]; c2[j] = 0;
}
}
cout<< c1[n] <<endl;
}