修長城 (區間DP)

2022-05-03 17:18:09 字數 2545 閱讀 8017

大家都知道,長城在自然條件下會被侵蝕,因此,我們需要修復。現在是21世紀,修復長城的事情當然就交給機械人來幹辣。我們知道,長城每時每刻都在受到侵蝕,如果現在不修復,以後修復的代價會更高。現在,請你寫乙個程式來確定機械人修長城的順序,使得修復長城的代價最小。

在這道題中,我們認為長城是一條很長的線段,長城的每個位置都有唯一的數字與它對應(即當前位置到長城某一端的距離)。這台機械人開始被放在乙個給定的初始位置,並以乙個恆定的速率行駛。對於每個損壞的地方,你都知道它具體的位置、現在修復的代價、以後修復代價會怎麼增加。由於機械人效率特別高,機械人每到損壞的地方就能瞬間將該位置修復(神秘)。

第一行三個整數 $n, v, x (1 \leq n \leq 1000, 1 \leq v \leq 100, 1 \leq x \leq 500000)$ ,分別表示長城損壞地方的數目、機械人在1個單位時間內移動的長度、機械人的初始位置。

接下來n行,每行三個整數 $x, c, u (1 \leq x \leq 500000, 0 \leq c \leq 50000, 1 \leq u \leq 50000)$ 。x代表損壞地方的位置。如果立即修復,則該損壞位置修復的代價為c。如果選擇在t時刻後修復,則該損壞位置修復的代價為c+u*t。資料保證所有損壞的位置都是不同的,機械人剛開始不會站在損壞的位置上面。

輸出只有乙個整數,修復整個長城的最小代價

(如果是小數,則向下取整)。

對於下面第一組樣例的解釋:

首先去998位置修復,費用為600。

然後去1010位置修復,費用為1400。

最後去996位置修復,費用為84。

最終答案為2084。

【樣例輸入1】

3 1 1000

1010 0 100 

998 0 300

996 0 3

【樣例輸入2】

3 1 1000

1010 0 100

998 0 3

996 0 3

【樣例輸出1】

2084

【樣例輸出2】

1138

鑑於這是乙個神級機械人,經過的地方都能瞬間修好,那麼被修好的地方都一定是連續的。在修的過程中,要麼向左修一下,要麼向右修一下,僅有兩種決策。這時想到區間dp。

dp中只需要計算增長的損失即可,原損失必然加到總和之中。

設$f_$表示已修好$[i,j]$,此時站在$i$上;設$g_$表示已修好$[i,j]$,此時站在$j$上。

如果從$[i-1,j]$擴充套件到$[i,j]$,所用時間為$t$,相當於$[1,i]$的點和$[j+1,n]$的點都有$t$的損失。用字首和維護$[1,i]$與$[j+1,n]$的總損失速度,乘上$t$加入代價中。

同理,從$[i,j-1]$擴充套件到$[i,j]$,所用時間為$t$,相當於$[1,i-1]$與$[j,n]$的點都有$t$的損失,同樣用字首和求出,計算這一步的代價。

字首和陣列$a_i=\sum\limits_^i u_i$

則$$\beginf_&=min(f_+(x_-x_i)*(a_i+a_n-a_j),g_+(x_j-x_i)*(a_i+a_n-a_j))\\g_&=min(f_+(x_-x_i)*(a_+a_n-a_),g_+(x_j-x_)*(a_+a_n-a_))\\\end$$

1.為了處理方便,可以多設定乙個毫髮無損的修復點代表起點。

2.dp陣列要開long long:為了精度問題,計算中先不除$v$,最後輸出的時候簡單處理一下再除$v$。

3.我的**裡面,$f$陣列多開了一維表示是站在左邊還是站在右邊,而不是這裡寫的$f$和$g$。

總體還是比較簡單的,當時沒有想到可以用字首和方便維護全域性的損失,寫得奇奇怪怪只有40,無語了。

1 #include 2 #include 3 #include 4 #include 5

using

namespace

std;

6 typedef long

long

ll;7 typedef double

db;8

const

int n=1010;9

intn,v,x,p;

10 ll f[n][n][2

],sum[n],ans;

11struct

node

16}s[n];

17int

main()

23 s[++n].x=x; s[n].c=s[n].u=0

;24 sort(s+1,s+1+n);

25for(int i=1;i<=n;i++)

29 memset(f,0x7f,sizeof

f);30 f[p][p][0]=f[p][p][1]=0

;31 ll t1,t2,out;32

for(int l=2;l<=n;l++)

33for(int i=1,j;i<=n-1;i++)

41 printf("

%lld\n

",(ans*v+(min(f[1][n][0],f[1][n][1])))/v);

42return0;

43 }

奇妙**

李志民 只修長城不會有真正的安全

5月12日以來,一款名為 wanna cry 的勒索病毒大規模攻擊全球電腦網路,據統計,涉及中國 日本 美國 整個歐洲等多國被入侵受害,其中英國醫療系統陷入癱瘓 大量病人無法就醫 中國 中石油 受波及到2萬個加油站斷網 西班牙電信巨頭等遭黑客攻擊。這起事件反映出多國在網路安全防範上的諸多不足,僅僅依...

線性dp 區間dp

1 尼克的任務 額一道挺水的題,愣是做了幾個小時 動態規劃大致的思路還是找乙個轉移 換個詞就是影響 我們可以明顯看出本題的規則 空暇時,一遇到任務必須挑乙個接 求1 n時間內最大空暇時間 所以將任務排序是必要的,兩個關鍵字 再來想象一下當我做到第i 個任務時,我在 st i st i t i 1 時...

線狀DP及區間DP

這裡我們都用到動態規劃的思想 dynamic programming,簡稱dp。本質就是組合子問題來求解原問題,且對每個子問題只求解一次。一般來說四個步驟 1.刻畫乙個最優結構特徵 2.遞迴的定義最優解值 3.計算最優解的值 4.利用計算出的資訊構造乙個最優解 這邊直接給出 include incl...