**
將乙個整數 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劃分成若...