学校を掛け以上2019電動C.ミルク(DP)

効果:$ N×m個の$ボード、$(1,1)$の横軸の初期位置は、$ \ FRAC {M + 1} {2} $することができ、ダウンしそうでないだけ回る、すべてのステップを取ることです$ 1 $秒$ T_I $時間ドリンクを過ごすために、$ k個の$管ミルク、$ I $タンクの位置$(R_iと、C_I)$を持っている。すべての$ 1 \ルI \ルのk $のために、ドリンクを取得牛乳で終わる$ I $最短チューブ。

 

書いた公式の説明によると、少し複雑$ DPの$のタイトルを達成。

主なアイデアは、各行左/右の$ X $ドリンクミルク缶の最小値に対して計算されると、その後、DP $合併答えを$。

#include <iostreamの> 
する#include <アルゴリズム> 
の#include <cstdioを> 
する#include <キュー> 
の#define REP(I、N)(iは= int型、iが<= N; I ++)のため
の#define PER( I、N)(I = N int型のために、I> = A; - I)
の#define X最初
の#define yの第二
の#define PBの一back 
名前空間stdを使用。
typedefの長い長いLL。
typedefのペア<int型、int型> PII。
constのLL INF = 1E15; 
CONST int型N = 1E4 + 10。
N INT、M、K、B [N]。
構造体{int型のX、Y、T;} [N]。
LL ANS [N]。
ベクター<PII> V [N]。
ベクター<LL>解く(ベクトル<PII> A、INT S、INT X){ 
	a.insert(a.begin()、PII(S、0)); 
	ベクター<LL> RET(a.size()、INF)、T(RET)。
	RET [0] = X == - 1 0:ABS(XS);?
	(I 1 = int型、iが(a.sizeを<); ++ i)について{ 
		INT LEN = ABS([I] .xa [I-1] .X)。
		REP(j、0、I-1)T [J] + = LEN。
		PER(j、1、i)をT [J] =分(T [J]、T [J-1] + [I] .Y)。
		REP(j、1、i)をRET [J] =分(RET [J]、T [J] +(X == - 1 0:ABS(XA [I] .X)))。
	} 
	RETを返します。
} 
ベクトル<LL>マージ(constのベクトル<LL>&L、constのベクトル<LL>&R){ 
	ベクトル<LL> RET(L.size()+ R.size() - 1、INF)。
	{(; iがL.sizeを()<++ iはi = 0 INT)のために
		(INT J = 0; J <R.size(); ++ j)のための{ 
			RET分(RET = [iがjで+] )L [I] + R [J]、[私はjは+]。
		} 
	} 
	戻りRET。
} 

ボイドワーク(){ 
	scanf関数( "%D%D%D"、&N、&M、およびK); 
	* B = 0。
	REP(I、1、K){ 
		scanf関数( "%D%D%D"、&
		B [++ * B] = [I] .X。
	} 
	B [++ * B] = 1。
	ソート(B + 1、B + 1 + * B)、* B =一意(B + 1、B + 1 + * B)-b-1。
	REP(I、1、* B)V [I] .clear(); 
	REP(I、1、K){ 
		[I] .X = LOWER_BOUND(B + 1、B + 1件の+ * B、[I] .X)-b。
		V [i]は.X] .pb(PII([I]・Y [i]が.T))。
		ANS [I] = INF。
	} 
	REP(I、1、* B)ソート((V [i])と、端部(V [i])と開始)。
	オートG =(V [1]、1、-1)を解きます。
	(I 0 = int型、iが(g.sizeを<); ++ i)について{ 
		ANS [I] =分(ANS [I]、G [I])。
	} 
	INT CUR = 0。
	ベクター<LL> F [2]。
	F [0] =(V [1]、1、(M + 1)/ 2)を解きます。
	REP(I、2、* B){ 
		CUR ^ = 1; 
		オートP = LOWER_BOUND((V [i])と、端部(V [i])と、PII((M + 1)/ 2,0)を開始します)。
		ベクター<PII> L、R(P、終了(V [I]))((V [i])と、P始めます)。
		(L)、終了(L)(開始)逆。
		自動f0は=(L、(M + 1)/ 2、(M + 1)/ 2)を解決するため、F1 =(R、(M + 1)/ 2、(M + 1)/ 2)を解きます。
		オートG0 =(R、(M + 1)/ 2、-1)解く=(L、(M + 1)/ 2、-1)、G1を解決します。
		G0 =マージ(F1、G0)、G1 =マージ(F0、G1)。
		オートG = G0。
		(INT J = 0; J <g.size(); ++ j)のための{ 
			G [J] =分(G [J]、G1 [J])。
		} 
		G =マージ([!CUR]のF、G)。
		F [CUR] =((F0、F1)をマージで、f [CUR!])マージ。
		(INT J = 0; J <g.size(); ++ j)のための{ 
			ANS [J] =分(ANS [J]、G [J] + B [I] -b [I-1])。
			F [CUR] [J] + = B [I] -b [I-1]; 
		} 
	} 
	REP(I、1、K){ 
		IF(I == K)のprintf( "%LLDを\ n"、ANS [I])。
		他のprintf( "%のLLD"、ANS [I]); 
	} 
} 


int型のmain(){
	一方、(t--)ワーク(); 
	int型のT。
	scanf関数( "%のD"、&T)。
}

 

おすすめ

転載: www.cnblogs.com/uid001/p/11249158.html