整數劃分 51Nod 1201 (經典dp)

2021-08-07 18:29:10 字數 1160 閱讀 7152

將n分為若干個不同整數的和,有多少種不同的劃分方式,例如:n = 6, ,共4種。由於資料較大,輸出mod 10^9 + 7的結果即可。

input

輸入1個數n(1 <= n <= 50000)。

output

輸出劃分的數量mod 10^9 + 7。

sample input

6sample output

4這道題 剛寫的時候 使用的 dfs 但是 由於 資料很大 ,所以 會超時 ,想著 優化一下,但是 dfs 與 bfs 本身 就是 比較 費時的 所以 就沒寫出來,其實 我自己 也想到啦 這道題 很可能是 用 dp 寫的, 但是 動態規劃方程 想不到 是什麼, 去網上 搜了 題解 才明白了, 感覺 真是 好題 所以 寫出來跟大家分享一下!

這道題的 動態轉移方程為:

dp[ i ][ j ] = dp[ i-j ][ j ] + dp[ i-j ][ j-1 ]

dp[ i ][ j ] 表示 用 j 個數 子 組成 i 的 不同的 組合種類, dp[ i-j ][ j ] 表示 組成 i-j 的 j 個數字 全部都 加上 乙個 一 之後 剛好 等於 i 剛好也是 用 j 個數 組成 i 的 不同 組合種類 中的 其中 一部分 種類, dp[ i-j ][ j-1 ] 表示的意思是: 用 j-1 個數 來組成 i-j+1 但是 呢 應為 原來 組成 i-j 的 j 個數 都已經 加上了 一 所以 都比一大 , 上式之所以仍然寫作 i-j 是應為 這裡 除了 j-1 個數字 之外 包含了 乙個 一 。我也是 想了之後 才明白的 !

#include 

#include

#include

#include

using

namespace

std;

const

int mod = 1e9 + 7;

int main()

ans = 0;

for(int j = 1; j < 350; j++)

ans = (ans + dp[n][j]) % mod;

printf("%d\n", ans);

}return

0;}

51Nod 1201 整數劃分 經典dp

題意不多說了。dp i j 表示i這個數劃分成j個數的情況數。dp i j dp i 1 j dp i 1 j 1 前者表示將i 1劃分為j個數,然後j個數都 1 還是不重複 後者表示將i 1劃分為j 1個數,然後j 1個數都 1,再加上1這個數 普通的dp是n 2的,但是可以發現1 2 m n 1...

51nod 1201 整數劃分

將n分為若干個不同整數的和,有多少種不同的劃分方式,例如 n 6,共4種。由於資料較大,輸出mod 10 9 7的結果即可。1 n 50000 直接一看就想到是一道最簡單揹包問題 但n 50000 然後我就直接上揹包,結果毫無疑問的超時,然後我的乙個夥伴在打二維揹包暴力時手抖打錯打出了正解 我們設f...

51nod 1201 整數劃分

1201 整數劃分 基準時間限制 1 秒 空間限制 131072 kb 分值 80 難度 5級演算法題 將n分為若干個不同整數的和,有多少種不同的劃分方式,例如 n 6,共4種。由於資料較大,輸出mod 10 9 7的結果即可。input 輸入1個數n 1 n 50000 output 輸出劃分的數...