ホテル
ミス・Dと遊びにかじる、私は部屋が4または7人を生きている場合、特に数4と7のような非常に奇妙なホテル、ホテルの所有者が、彼はとても幸せになりますか、彼もこの部屋に住みたいと思わなかったました。今、あなたに各部屋(7以下)に住む人々の数を教えてくれ、部屋はABS(IJ)で部屋の人々のJ i個の原価に移動します、所有者の要件を満たすために、支出の費用はどのくらいですか?
入力
数nの最初の行を、部屋の数
第二行nの数は、元の家の各部屋における人の数
出力
所有者の要求に応じて、最小コストを表す数値が
分布が必要とされない場合、出力の-1
100%:1 <= N <= 1E5
問題の解決策
状態のデザインは、i番目のモバイルJ室後方ルーム個々の部屋と動作条件のi番目の最小数が満たされているため、[I] [J] fを、考えることは困難です。
7個々の部屋の最大ので、そう7つの個体の最大値は、後方に移動するだけでなく、基板7に来るシフト、第二寸法14を参照します。
この部屋から列挙の転送と隣の部屋には、それは考慮に入れ、すべての事情を取ることができるように多くの人々が、判明する方法を入れたとき。
n番目の部屋が出て転送することができないので、最後に、n-1が、部屋に答えます。
#include <cstdioを> する#include <CStringの> する#include <iostreamの> する#include <アルゴリズム> 使用して 名前空間STD; のconst int型 MAXN = 100005 ; のconst int型 INF = 1061109567 ; INT N-、A [MAXN]; INT F [MAXN] [ 20 ]; // Jのうちの部屋にI + 1の個々の最低作動室(J <7入力するi番目の テンプレート < クラス T>をインラインボイド読む(T&X){ X = 0 ; int型 F = 0 ; CHAR CH =getchar関数(); 一方、 {F | =(CH ==(isdigit(CH)!)' - '); CH = GETCHAR();} ながら(isdigit(CH)){X =(X << 1)+(X << 3)+(CH ^ 48)、CH = GETCHAR();} 、X = F?- X:X; } int型の ABS(int型 X){ 戻り X < 0?- X; X} ブール CX(INT X){ 場合(!X || X == 4 || X == 7)を返す 真。 返す 偽; } INT メイン(){ freopenは(" hotel.in "、" R " 、STDIN)。 freopenは(" hotel.out "、" W " 、STDOUT)。 (n)を読み出します。 以下のために(int型 i = 1 ; iが<= N; iは++ )読み出す([I])。 memsetの(F、0x3fを、はsizeof (F))。 F [ 0 ] [ 7 ] = 0 。 以下のために(int型 i = 0 ; iがn <; iは++ ) のために(int型 J = 0 ; J <= 14 ; J ++ ) 場合!(F [I] [J] = INF){ int型 で = J = 7 ; 用(int型のk = 0 ; K <= 14 ; ++ k個){ int型 アウト = K- 7 。 もし(CX([I + 1 ] + に - アウト)) F [I + 1 ] [K] =分(F [I + 1 ] [K]、F [i]は[J] + ABS(アウト))。 } } int型 ANS = INF; のための(int型 I = 0 ;私は= < 14 Iは++; ) IF(CX([N-] A + I- 7))// N-なし後継、N-1からの回答 ANS =分( ANS、F [N- 1 ] [I]); のprintf(" %のD "、ANS == INF - ?1 :ANS); }
贈り物
ミス・Dにかじる長さnの贈り物を用意し、mはまた、彼はこのギフトを達成を助けるために友人を可能にする、誰もが位置pを立ち始め、xの連続した長さの一部としてドレスアップ、人が参加することはできません関与したら、彼は一部が、彼はステーションを開始した位置を含んでいなければならない服を着て。誰もが、全体の美しい贈り物の最高値をしたいかじる、それをY度を高めるためになり、全体の美しい贈り物をすることができますロングドレスのパート1ですか?
入力
最初の二つの整数行nmで、長さは、友人の贈り物の数を表します。
三つの整数の次のn行は、それぞれ、人が美しさと初期位置に長さをドレスアップ。
出力
ギフト最大の美しさの全体の値を表す整数
1 <= N <= 16 000
1 <= M <= 100
1 <= Y <= 10 000
PS:それは法的な間隔でpは彼が描いた場合。
問題の解決策
Fを考える美しいが、私jの個々のユニット、列挙ポイント範囲左右の点jの(K、J]前に塗装する前に[i] [j]が最大値を表していることができます。
F [I] [J] = MAX(F [I-1] [K] +(J-K)* Y)は、k + 1 <= p <= J、及び区間長jは以下であります
これは、pを選択するために、一定の範囲を保証します
[I] [J] = MAX(F [I-1] [K] + -kyのJY)Fクリック字形変異
JYは、Fの最大限り、一定である[I-1] [k]を-ky、キューが単調(最大値を選択する摺動部)に維持することができます
誰かが前に置くが、状態には影響しませんことができれば、その状態が大きくなる可能性があるため、pで並べ替えることがわかりました。
#include <cstdioを> する#include <iostreamの> する#include <アルゴリズム> 使用して 名前空間STD; CONST INT MAXN = 16005 ; のconst int型 MAXM = 105 ; INT N-、M; INT F [MAXM] [MAXN]; // 個々のI前最大フロントトリムJユニットは int型H、T、S [MAXN]と、 構造体人{ int型のX、Y、POS; BOOLの 演算子 <(CONST人物A){ 戻り <POSをa.pos;} } [MAXM] ; テンプレート < クラス T>インラインボイドリード(T&X){ X = 0。int型の F = 0 ; チャー CH = GETCHAR()。 一方、 {F | =(CH ==(isdigit(CH)!)' - '); CH = GETCHAR();} ながら(isdigit(CH)){X =(X << 1)+(X << 3)+(CH ^ 48)、CH = GETCHAR();} 、X = F?- X:X; } INT GET(int型私は、int型の jは、INT W){ リターン [I] [J] F -j * W;} int型メイン(){ freopenは(" gift.in "、" R " 、STDIN)。 freopenは(" gift.out "、" W " 、STDOUT)。 (n)を読み出す;(m)を読み出します。 用(int型 iは= 1 ; I <= M; iが++ )読み出す([I] .X)、読み取り([I]・Y)、([I] .POS)読み取ります。 ソート(A + 1、+のM + 1 )。 以下のために(int型 I = 1 ; I <= M; iは++ ){ H = 1、T = 0 。 ために(のInt J = 0 ; J <= N; J ++ ){ F [I] [J] = MAX(F [I- 1 ] [J]、F [I]、[J- 1 ]); // 接頭求めて最大値 IF(J <a [I] && .POS J + A [I] .x> = A [I] .POS){ // にf層に入れ ながら(H <= T && GET(I- 1、 S [T]、A [I] .Y)< GET(I- 1、J、A [I] .Y))T-- ; S [ ++ T] = J; } IF(J> = A [ I] && .POS J <[I] .POS + [I] .X){ // 右POS点後確保するために更新が選択POS ながら(H <T && S = [H] + [I] .X <J)H ++。 F [I] [J] = MAX([I] [J] F、取得し(I- 1 [I] .Y)+ J *、S [H]を[I] .Y)。 } } } のprintf(" %dの" 、F [M] [N])。 }