總時間限制: 200ms 記憶體限制: 65536kb
描述
將正整數n 表示成一系列正整數之和,n=n1+n2+…+nk, 其中n1>=n2>=…>=nk>=1 ,k>=1 。
正整數n 的這種表示稱為正整數n 的劃分。
輸入
標準的輸入包含若干組測試資料。每組測試資料是一行輸入資料,包括兩個整數n 和 k。
(0 < n <= 50, 0 < k <= n)
輸出
對於每組測試資料,輸出以下三行資料:
第一行: n劃分成k個正整數之和的劃分數目
第二行: n劃分成若干個不同正整數之和的劃分數目
第三行: n劃分成若干個奇正整數之和的劃分數目
樣例輸入
5 2
樣例輸出
2
33
提示
第一行: 4+1, 3+2,
第二行: 5,4+1,3+2
第三行: 5,1+1+3, 1+1+1+1+1+1
#include
#include
using
namespace std;
//a[i][j] 和為i, j個正整數
////第一行: n劃分成k個正整數之和的劃分數目 a[i][j] j=k
//第二行: n劃分成若干個不同正整數之和的劃分數目 b[i][j] i=n不同正整數
//第三行: n劃分成若干個奇正整數之和的劃分數目 c[i][j] i=n 奇正整數
//a//初始狀態: a[i][1]=1
//分類——包含1和不包含1
//a[i][j]=a[i-1][j-1]
// +1就為當前值——故必包含1
// if i-j>j ---- a[i][j]+=a[i-j][j] 每個整數-1,則原來為1的就為0了
int a[60]
[60]=
;voidq1(
int n,
int k)
for(
int i=
1;i<=n;i++)}
}}//n劃分成若干個不同正整數之和的劃分數目
//最大值為t=n的不同正整數之和
//b[i][j]= 不包括n和包括n 從前t(1——t)種數字鐘選擇一些——湊成和i的做法數目
// 如果i=0; return1;
// 如果t=0; return0;
// return [i][t-1]+[i-t][t-1]
int b[60]
[60]=
;voidq2(
int n,
int t)}}
// n劃分成若干個奇正整數之和
//與整數拆法類似——考慮有沒有1
//沒有1—— -2*j
//因為沒有1的話最小的就為3以上
//c[i][j]=c[i-2*j][j]+c[i-1][j-1]
// 沒有1的 所有有1的
// 每個都減去2 ——減一的話就都剩偶數了——-2就為計數
int c[60]
[60]=
;voidq3(
int n,
int t)
for(
int i=
2;i<=n;i++)}
}}int n;
int k;
intmain()
}
解題思路
使用動態規劃需要滿足的條件:
子問題的最優解可以用於遞推母問題的最優解;
問題一
將n劃分成k個正整數之和,求可劃分的數目。
a[i][j]表示j個正整數求和為i;
目標為a[n][k]
初始狀態:a[i][1]=1
難點:
分類方法: 表示式中包含1和不包含1
包含1的表示式——a[i][j]=a[i-1][j-1]
,即前乙個數所有的表示式+1即可;
不包含1的表示式——a[i-j][j]
,當作最小為2,則每個數-1後最小為1。
int a[60]
[60]=
;voidq1(
int n,
int k)
for(
int i=
1;i<=n;i++)}
}}
問題2
n劃分成若干個不同正整數之和的劃分方法總數;
b[i][j], i劃分成小於等於j的不同正整數之和的劃分方法數;
目標為b[n][n]
初始狀態:b[0][0]=1; ——0的和為0
難點:
遞推方法 ——當前b[i][j]的方法數等於包含j和不包含j的方法數相加
遞推公式
不包含j的方法數——b[i][j-1]
包含j的方法數——b[i-j][j-1] (i>=j時),i遞推方向——(先從左往右推)——(再從上往下推)–初始狀態確定0,0即可
int b[60]
[60]=
;voidq2(
int n,
int t)
}}
問題3
n劃分成若干個奇正整數之和,求劃分方法數
c[i][j]——用j個數求和i
總劃分數為i行所有j的和。
初始狀態——c[i,i為奇數][1]=1,因為乙個數只有一種表示式
分類方法
包含1——c[i-1][j-1]
不包含1——c[i-2j][j], (i>3j),因為如果i<3*j,表示式中必含1
目標為c[n][1]加到c[n][n]的和;
int c[60]
[60]=
;voidq3(
int n,
int t)
for(
int i=
2;i<=n;i++)}
}}
與問題一:n劃分成k個整數之和的劃分方法數做法相同。
k從1取到n的和就為總的方法數;
求j個數中不包含1的和為i的表示式
此表示式全部大於等於3,則每個數-2,最小值為1,也有不包含1的。
[i-2j][j]的總數為[i][j]中不包含1的數量。
動態規劃解整數劃分
演算法思路 n n1 n2 n3 n4 nk n1 n2 n3 nk 從大到小排列後,可以避免陷入數值大小排序順序的困境中。這樣,在下面的過程,我們可以並不關心數值大小的排列,只關心組合方案數。狀態表示 將最大加數n1不大於m的劃分個數記作q n,m 狀態轉移 1 q n,1 1,n 1 當最大加數...
整數劃分問題 動態規劃
原文出處 整數劃分 有以下情況 1 將n劃分成若干正整數之和的劃分數。2 將n劃分成k個正整數之和的劃分數。3 將n劃分成最大數不超過k的劃分數。4 將n劃分成若干奇正整數之和的劃分數。5 將n劃分成若干不同整數之和的劃分數。include includeconst int ns 55 int n,...
DP 動態規劃 整數劃分
時間限制 3000 ms 記憶體限制 65535 kb 難度 3 輸入第一行是測試資料的數目m 1 m 10 以下每行均包含乙個整數n 1 n 10 輸出輸出每組測試資料有多少種分法。描述將正整數n表示成一系列正整數之和 n n1 n2 nk,其中n1 n2 nk 1,k 1。正整數n的這種表示稱為...