遞迴 DP 2749 分解因數

2021-08-28 05:09:45 字數 1345 閱讀 7356

題目鏈結: 描述

給出乙個正整數a,要求分解成若干個正整數的乘積,即a = a1 * a2 * a3 * ... * an,並且1 < a1 <= a2 <= a3 <= ... <= an,問這樣的分解的種數有多少。注意到a = a也是一種分解。

輸入第1行是測試資料的組數n,後面跟著n行輸入。每組測試資料佔1行,包括乙個正整數a (1 < a < 32768)

輸出n行,每行輸出對應乙個輸入。輸出應是乙個正整數,指明滿足要求的分解的種數

定義 dp[i][j] 表示將 i 分解成不大於 j 的因數的個數

i 如果能分解出來 j ,即為 i%j == 0;那麼其可以由兩種互斥的情況組成:

如果最終的劃分結果有至少乙個 j 那麼其種類數為 dp[ i/j ][j] (注意下次最大劃分數仍是 j,表示下一次仍然可以劃分出 j,如果要求分解的每個數不重複,那麼改為 dp[ i/j ][ j-1 ] 即可)

如果最終的劃分結果連乙個 j 都沒有,那麼其種類數為 dp[i][ j-1 ]

比如  8%2==0,dp[8][2] = dp[4][2] + dp[8][1],前面的是至少有乙個2(然後把這個2劃分出去,剩下的部分組合的數量是 dp(4, 2)),後面的是沒有劃分出2(那麼劃分出來最大的數就是1),i 如果不能分解 j,即為 i%j != 0 ,那麼 dp[i][j] = dp[i][ j-1 ]。

總結:if( i%j ==0 )  dp[i][j] = dp[i][ j-1 ] + dp[ i/j ][j];

else  dp[i][j] = dp[i][ j-1 ];

然後尋找出口

1.  if( j>i ) dp[i][j] = dp[i][i]

2.  dp[1][1] = dp[1][0] + dp[1][1] 

3.  dp[2][2] = dp[2][1] + dp[1][1] = 1  

根據上面兩行推導出 dp(2, 1) = 0,dp[1,1] = 1,可以推導if( i>1 )  dp(i,1) = 0。

總結得到出口條件:

i==1  return 1;

j==1  return 0;

注意上面兩行是有順序的,不能顛倒。

參考部落格:

int solve(int i, int j)  //本題資料量太小 ,不用記錄狀態,遞迴即可直接a

int main()

return 0;

}

int dp(int i, int n) 

return ans;

}int main()

return 0;

}

2749 分解因數

2749 分解因數 總時間限制 1000ms 記憶體限制 65536kb 描述給出乙個正整數a,要求分解成若干個正整數的乘積,即a a1 a2 a3 an,並且1 a1 a2 a3 an,問這樣的分解的種數有多少。注意到a a也是一種分解。輸入第1行是測試資料的組數n,後面跟著n行輸入。每組測試資料...

2749 分解因數

description 給出乙個正整數a,要求分解成若干個正整數的乘積,即a a1 a2 a3 an,並且1 a1 a2 a3 an,問這樣的分解的種數有多少。注意到a a也是一種分解。input 第1行是測試資料的組數n,後面跟著n行輸入。每組測試資料佔1行,包括乙個正整數a 1 a 32768 ...

2749 分解因數 POJ

總時間限制 1000ms 記憶體限制 65536kb 描述給出乙個正整數a,要求分解成若干個正整數的乘積,即a a1 a2 a3 an,並且1 a1 a2 a3 an,問這樣的分解的種數有多少。注意到a a也是一種分解。輸入第1行是測試資料的組數n,後面跟著n行輸入。每組測試資料佔1行,包括乙個正整...