整數劃分-劃分數(DP動態規劃)
阿新 • • 發佈:2018-12-30
給你一個正整數n,讓你計算出n的m劃分有幾種方法。
思路:定義dp[i][j]為i的j劃分,即將i劃分為j個數字之和的方案數。
1:當j<=i時,此時,劃分個數不超過i,此時是正常的劃分。
劃分的結果一定只有兩種型別:一種是j個數字,都大於0。另一種是有0,即不夠劃分j個,用0來湊的。
j個數字中存在0的,其實就是前一個劃分j-1的方案數,補0就行,即dp[i][j-1]。
j個數字均大於0的,此時也能呼叫之前的解求出,已經當前j個數字均大於0,我們將每個數字都減去1,此時在保證j個數字結構不變,且非負的情況下,dp[i-j][j]就是當前dp[i][j]不為0的方案數。
2:當j>i,此時劃分個數超過i本身,此時j個數字必然存在0,且只有這一種情況,此時直接dp[i][j-1];
j<=i時:dp[i][j]=dp[i][j-1]+dp[i-j][j]
j > i時:dp[i][j]=dp[i][j-1]
程式碼:
#include<bits/stdc++.h> ll dp[550][550],n,m; int main() { while(~scanf("%lld%lld",&n,&m)) { memset(dp,0,sizeof(dp)); for(ll i=1;i<=m;i++)dp[0][i]=1; for(ll i=1;i<=n;i++) { for(ll j=1;j<=m;j++) { if(j<=i)dp[i][j]=dp[i][j-1]+dp[i-j][j]; //此時兩種情況相加 else dp[i][j]=dp[i][j-1]; //此時只有存在0這一種情況 } } printf("%lld\n",dp[n][m]); } return 0; }