質問の意味:N冊与えられ、それぞれの本はページ数が異なると、このm個のM帳で個人的な外観を与えます
答えは、重みのページのほとんどは、最小の重みの値を必要とし、個々の表情をmのことです
アイデア:列挙長さの数を列挙した後に最適解を見つけるための最初の間隔DP次元二次元
しかし:この質問は、複数のソリューションを有していてもよく、彼は少数の人々が解決策を読んで、以前の出力を尋ねました
私は三次元を開くために始めても、これが出るように答えが少ないの回答を読んで、人々の前で、必ずしもではないが、答えの位置を表すために来ます
だから、最終的に最適解への再帰的なアプローチに置き換え
0位置1を表し、三次元で被験者の体重であります
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1の#include <ビット/ STDC ++ H> 2 使用して 名前空間STDを、 3 4 CONST INT MAXN = 5E2 + 10 。 5 のconst int型 INF = 0x3f3f3f3f 。 6 INT DP [MAXN] [MAXN] [ 2 ]。 7 INT A [MAXN]。int型の合計[MAXN]。 8 構造体ノード 9 { 10 INTは、左右しました。 11 } G [MAXN]。 12の ボイド RES(int型のx、int型ANS) 13 { 14 もし(!x)が復帰。 15 のために(INT ; I> = I = X 0 ; i-- ){ 16 であれば(和[X] -sum [I- 1 ]> ANS ||!I){ 17の RES(I、ANS)。 18 のprintf(" %D%D \ n "、I + 1 、X)。 19 ブレーク; 20 } 21 } 22 } 23 のint main()の 24 { 25 INT N、M。 26 のscanf("%D%D "&N、& M); 27 のmemset(DP、INF、はsizeof (DP)); 28 のために(INT iは= 1 ; I <= N; I ++ ){ 29 のscanf(" %dの」、&A [I]); 30 和[I] =和[I- 1 ] + [I]; 31 DP [I] [ 1 ] [ 0 ] = 和[i]は、 32 DP [I] [ 1 ] [ 1 ] = 1 ; 33 } 34 のために(INT私は= 2 ; I <= M; I ++ ){ 35 のために(INT J = 1 ; J <= nであり、j ++ ){ 36 // DP [j] [i]が[0] = MAX(DP [J-1] [I-1] [0]、[J])。 37 // DP [J] [I] [1] = J。 38 のための(int型 K = 2 ; K <= J K ++ ){ 39 INT TMP = MAX(DP [K- 1 ] [I- 1 ] [ 0 ]、和[J] -sum [K- 1 ])。 40 であれば(TMP <DP [j] [i]が[ 0 ]){ 41 、DP [J] [I] [ 0 ] = TMP。 42 DP [J] [I] [ 1 ] = K。 43 } 44 } 45 } 46 } 47 int型 塩基 = N。 48 のために(INT I = M、I> = 1 ; i-- ){ 49 G [i]が.LEFT = DP [ ベース ] [I] [ 1 ]。 50 G [i]が.RIGHT = 塩基; 51 塩基 = DP [ ベース ] [I] [ 1 ] - 1 。 52 } 53 // (I ++; I <= M INT iが= 1)についての 54 // のprintf( "%D%D \ n"は、G [i]が.LEFT、G [i]が.RIGHT)。 55の RES(nは、DP [n]は[M] [ 0 ])。 56 リターン 0 。 57 }