hdu4261(プライオリティキュー+ DP)

トピックリンク:http://acm.hdu.edu.cn/showproblem.php?pid=4261

問題の説明
「あまりにも多くの数字があります!」あなたの上司の轟音。「どのように私はこれらすべてを理解する必要があります?!見積りダウンそれを入れて!」 
あなたが失望されています。これらの数字は、多くの作業を生成する必要があります。ただし、所有者の要件に合わせてそれを行います。
あなたは、以下の方法で推定することが決定:あなたはデジタル配列持ち A.を あなたはに分割されます kの 連続した部分、その大きさは必ずしも同じではありません。その後、あなたはセクション全体を推定するために番号を使用します。換言すれば、サイズ のnの 配列 A あなたはサイズの別の作成することが、 N個の アレイ B 有し、 k個 の連続する部分を。同じiとjの一部ならば、 B  [I] =  B  [J]。(あなたは絶対差の和として表され、エラーを最小限にしたい [シグマ  |  A  [I]  -B  [I] |)。
エントリー
入力のいくつかのテストケース。各テストケースは、ラインに二つの整数で始まる Ñ (1≦  Ñ  ≤2,000)及び K (1≦  K  ≦25、 K  ≤  Ñ )、 Nは アレイの大きさであり、 kは 連続番号であります一部を推定します。配列 A 次回 のn 行、各行整数。 Aは -10000(含む)〜10,000の整数要素の範囲。入力は2ゼロで終了します。
出力
各テストケースについては、あなたが達成できることを最小の誤差があり、独自のライン出力整数、上。出力されていない余分なスペースを行い、空白行は、あなたの答えを区切る使用しないでください。回答を生成するすべての可能な入力が、答えは64ビット符号付き整数に適しているであろう
サンプル入力
7 2
6
5
4
3
2
1
7
0 0
サンプル出力
9

(|愛のBi |)最小Kの部分に、Aの配列を与えられ、各部分は、1つが与えられ、B、例えばシグマのすべてのこと:問題の意味

ソリューションの概要:まず、状態DP [i]の[j]を定義します。i番目の分割ブロックjの最小コストの前に。[J] =分(DP [M] [I-1] + iは考慮Aに分割された(M + 1))[I] DP得ることは容易です。重要な問題は、その後、片にコストの範囲のすべてを得ることが可能となります。各間隔のために、考えることは容易である:ブロックAに対応し、この配列割当ブロックBは、配列の中央値は、この時点で最小のコストです。中央値を検索する方法についてように、2つのプライオリティキュー、優先度の大きな値を定義することができ、優先度の値が小さく、その2つのキュー、最初のチームの二つのセクションの中央値に各区間平均その後、1、およびそれにその価格帯を見つけます。

#include <ビット/ STDC ++ H> 
名前空間STDを使用して、
const int型MAXN = 2E3 + 5。
INT DP [MAXN] [30]。
int型TEM [MAXN] [MAXN]。
[MAXN] int型。
const int型INF = 0x3f3f3f3f。
PRIORITY_QUEUE <int型、ベクトル<整数>、大きい<整数>> QUE1。
PRIORITY_QUEUE <整数> que2。
INT()は、メイン{ 
	INT N、K。
	一方、(!のscanf( "%D%D"、&N&K)= EOF){ 
		IF(N == 0 && K == 0){ 
			戻り0; 
		} 
		ため(INT iは= 0; I <= N; I ++){ 
			ため(INT J = 1; J <= K; J ++){ 
				DP [I] [J] = INF。
			} 
			DP [i]は[I] = 0; 
		} 
		{(; <I = N I ++ iは1 = INT)のため
			のscanf( "%dの"、および[I])。
			
		} 
		(INT iについて1 =; I <= N。
			(!que2.empty()))(que2.pop中。
			int型SUM1、SUM2。
			SUM1 = SUM2 = 0。
			(; J> = 1; INT J = J - )は{ 
				int型L1 =(I-J + 2)/ 2。
				INT L2 =(I-J + 1)/ 2。
				INT T = A [J]。
				IF(que1.empty()){ 
					SUM1 + = T。
					que1.push(T)。
				} 
				他{ 
					もし(T> que1.top()){ 
						SUM1 + = t-que1.top()。
						que1.push(T)。
						T = que1.top()。
						que1.pop(); 
					} 
					IF(!que2.empty()&& T <que2.top()){ 
						SUM2 + = t-que2.top()。
						que2.push(T)。
						T = que2.top()。
						que2.pop(); 
					} 
					IF(que1.size()<L1){ 
						SUM1 + = T。 
						que1.push(T)。
					} 
					他{ 
						SUM2 + = T。
						que2.push(T)。
					} 
				} 
				、T = que1.top()。
				INT T1 = -1。
				(!que2.empty())の場合
				 	、T1 = que2.top(); 
				IF((I-J + 1)&1){ 
					TEM [j]は[I] = SUM1-T * L1 + T * L2-SUM2。
				} 
				他{ 
					TEM [j]は[I] =分(SUM1-T * L1 + T * L2-SUM2、SUM1-T1 * L1 + T1 * L2-SUM2)。
				} 
			} 
		} 
		のために(INT I 1 =; I <= N; I ++){ 
			DP [I] [1] = TEM [1]〜[I]。
		} 
		(INT iは2 = I ++; I <= k)に対する{ 
			ための(int型J = I; J <= nであり、j ++){ 
				ため(INT m = 1であり; M <Jであり; m ++){ 
					DP [J] [ I] =分(DP [j] [i]は、DP [m]は[I-1] + TEM [M + 1]〜[J])。
				}
			}	 
		}  
		のprintf( "%D \ n"は、DP [n]が[K])。
	}
	0を返します。
}

  

 

 

おすすめ

転載: www.cnblogs.com/Zhi-71/p/11862522.html