對整數劃分,關鍵點:
1、找出動態規劃的狀態轉移方程
2、確定各種情況下的初始條件
description
將正整數n表示成一系列正整數之和:n=n1+n2+…+nk,其中n1>=n2>=…>=nk>=1。正整數n的這種表示稱為正整數n的劃分。求正整數n的不同劃分個數。例如,正整數6有如下11種不同的劃分:6: 6; 5+1; 4+2; 4+1+1; 3+3; 3+2+1; 3+1+1+1; 2+2+2; 2+2+1+1; 2+1+1+1+1; 1+1+1+1+1+1.
input
多組測試資料,輸入到檔案結束,每組資料報含乙個正整數n(n<=40)
output
輸出n的不同劃分個數。
sample input3 6
sample output
3 11
【題目分析】
用dp[i][j]表示將i拆分成若干個數字,最大的那個數字不超過j的方案數。那麼包括兩種情況:第一種是最大的數不超過j-1,此時方案數是dp[i][j-1];否則數字剛好是j,因為劃分中存在最大值j,所以可以在(i-j)中繼續以最大值為j來劃分,此時方案數是dp[i-j][j],(若題目要求不重複則為dp[i-j][j-1])所以可得狀態方程:
dp[i][j]=dp[i][j-1]+dp[i-j][j], i>=j
dp[i][j]=dp[i][i], i
當 i == 1 || j == 1 時,dp[i][j]= 1, 因為i為1,那麼只能劃分為1; 而j為1,那麼只能劃分成i個1.
當 i == j 時,dp[i][j]=dp[i][j-1]+dp[0][j],可知dp[0][j] = 1,即劃分數字正好等於自己
最後的dp[n][n]就是答案。
#include
int dp[1005][1005];
void integer_partition(int n)
for(int i=2;i<=n;i++)}}
}int main(int argc, const
char * argv)
dp[n][k],則是數n的劃分中,其最大值不能大於k的劃分個數。
題目描述 description
將整數n分成k份,且每份不能為空,任意兩種劃分方案不能相同(不考慮順序)。
例如:n=7,k=3,下面三種劃分方案被認為是相同的。
1 1 5
1 5 1
5 1 1
問有多少種不同的分法。
輸入描述 input description
輸入:n,k (6輸出描述 output description
輸出:乙個整數,即不同的分法。
樣例輸入 sample input
7 3樣例輸出 sample output
4資料範圍及提示 data size & hint
【題目分析】
用dp[i][j]代表i分成j個部分有幾種分法.
當 i < j 時,顯然是不可能的,那麼dp[i][j] == 0;
當 j == 1 時,dp[i][j] == 1;
當i >= j 時,d[i][j]=d[i-j][j]+d[i-1][j-1],前半部分對應這j個數中不存在1的情況,那麼我們就可以將劃分中每個數都減去1,剩下的輸仍然是大於0的,等價於將i減去了j,而後半部分這是對應這j個數中存在1的情況
且當 i == j 時,dp[i][j]=dp[i-1][j-1]+dp[0][j]=1,可知dp[0][j] =0
最終程式可以如下:
#include如果要求是可以小於j個部分,那麼就可以將結果從1一直加到j。int dp[1005][1005];
void integer_partition(int n, int m)
for(int i=2;i<=n;i++)else}}
}int main(int argc, const
char * argv)
1.劃分個數不固定,可用模型1(有最大值j無最大值j):
for(int i = 0; i <=
n; i++)
for(int
i = 1; i
<= n; i++) else
} }
2.劃分個數固定,用模型2(有1沒1): 整數劃分問題 經典DP
相關題目1 相關題目2 相關題目3 下面的描述大部分借鑑於 感謝,但是其中有部分錯誤,我會在下面的描述中糾正過來 總的解決方法時截邊法,也就是去討論有1無1的情況和截去他們的情況 記住了.1.若劃分的多個整數可以相同 設dp i j 為將i劃分為不大於j的劃分數 1 當i j 時,i不能劃分為大於i...
哈理工OJ 2004 整數劃分(經典dp問題)
整數劃分 time limit 1000 ms memory limit 32768 k total submit 143 109 users total accepted 115 104 users rating special judge no description 將正整數n表示成一系列正整...
南陽理工oj 整數劃分(DP)
問題是我們經常見到的整數劃分,給出兩個整數 n m 要求在 n 中加入m 1 個乘號,將n分成m段,求出這m段的最大乘積輸入 第一行是乙個整數t,表示有t組測試資料 接下來t行,每行有兩個正整數 n,m 1 n 10 19,0 m n的位數 輸出 輸出每組測試樣例結果為乙個整數佔一行 樣例輸入 2 ...