整數劃分問題 動態規劃 遞迴

2021-06-20 17:39:21 字數 1741 閱讀 2939

** 

將乙個整數 n 劃分為 不超過m 組 的劃分數 如 

n=4m=3

輸出:4

思路:使用動態規劃: 定義狀態: 

dp[i][j] j的i劃分的組數

遞推:dp[i][j]=dp[i][j-i]+dp[i-1][j] ------當m=n時,變成了常見的整數劃分問題

[cpp]view plain

copy

#include

#include

using

namespace

std;  

const

intmaxn=1000+10;  

intdp[maxn][maxn],n,m;  

void

sovle()  

else

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

}  }  

}  int

main()    

我們用遞迴+記憶化的方法來解決普通整數劃分問題:定義 f(n,m)為將整數n劃分為一系列整數之和,其中加數

最大不超過m。

得到下面的遞推關係式:

當n==1 || m==1 只有一種劃分,即 1 或者 1+1+1......+1

當m>n 顯然,等價於 f(n,n)

當m==n 此時:我考慮加數包含m與否的兩種情況:

1)劃分不包含m,即f(n,m-1)---所有m-1的劃分

2)劃分包含 m,此時只有一種即 m

所以當m==n時,有 f(n,m)=f(n,m-1)+1 當m

1)包含m時,此時 等價於 f(n-m,m)

2)不包含m時,顯然f(n,m-1)

所以f(n,m)=f(n,m-1)+f(n-m,m)

採用記憶化技術優化複雜度:

[cpp]view plain

copy

#include

#include

using

namespace

std;  

const

intmaxn=1000+10;  

intf[maxn][maxn];  

intgetspilit(

intn,

intm)  

if(n==m)   

return

f[n][m]=(getspilit(n-m,m)+getspilit(n,m-1));  

}  int

main()    

將整數n劃分為一系列連續的整數之和即:

15=7+8

=4+5+6

=1+2+3+4

這裡我們假設劃分之後最小的整數字x ,那麼 x+(x+1)+(x+2)......+(x+m)假設一共有i個整數,整理得:

x*i+i*(i-1)/2=n

i=1,2,3.....其中i的限制條件為:s1=i*(i-1)/2<=n,只有當x為整數時才有可能。

[cpp]view plain

copy

#include

#include

using

namespace

std;  

intgetsplit(

intn)  

}  return

sum;  

}  int

main()    

整數劃分問題 動態規劃

原文出處 整數劃分 有以下情況 1 將n劃分成若干正整數之和的劃分數。2 將n劃分成k個正整數之和的劃分數。3 將n劃分成最大數不超過k的劃分數。4 將n劃分成若干奇正整數之和的劃分數。5 將n劃分成若干不同整數之和的劃分數。include includeconst int ns 55 int n,...

整數劃分系列問題(動態規劃)

今天上演算法分析與設計課時,提到整數劃分問題,但是因為之前沒有很好地理解這一系列的問題。當被老師問到你們做演算法的應該會這個問題吧,我當時也不太記得,但是只能硬頭皮試著去寫了下,用的是brute force,老師果斷說我的方法跑不出正確的解,但是課堂上我也沒有去解釋了。課後自己驗證了一下,沒有問題,...

動態規劃 整數劃分問題(2)

整數劃分 乙個老生長談的問題 1 練練組合數學能力.2 練練遞迴思想 3 練練dp 總之是一道經典的不能再經典的題目 這道好題求 1.將n劃分成若干正整數之和的劃分數。2.將n劃分成k個正整數之和的劃分數。3.將n劃分成最大數不超過k的劃分數。4.將n劃分成若干奇正整數之和的劃分數。5.將n劃分成若...