洛谷P1220 關路燈 搜尋

2021-08-21 14:26:40 字數 3061 閱讀 9840

某一村莊在一條路線上安裝了n盞路燈,每盞燈的功率有大有小(即同一段時間內消耗的電量有多有少)。老張就住在這條路中間某一路燈旁,他有一項工作就是每天早上天亮時一盞一盞地關掉這些路燈。

為了給村里節省電費,老張記錄下了每盞路燈的位置和功率,他每次關燈時也都是盡快地去關,但是老張不知道怎樣去關燈才能夠最節省電。他每天都是在天亮時首先關掉自己所處位置的路燈,然後可以向左也可以向右去關燈。開始他以為先算一下左邊路燈的總功率再算一下右邊路燈的總功率,然後選擇先關掉功率大的一邊,再回過頭來關掉另一邊的路燈,而事實並非如此,因為在關的過程中適當地調頭有可能會更省一些。

現在已知老張走的速度為1m/s,每個路燈的位置(是乙個整數,即距路線起點的距離,單位:m)、功率(w),老張關燈所用的時間很短而可以忽略不計。

請你為老張編一程式來安排關燈的順序,使從老張開始關燈時刻算起所有燈消耗電最少(燈關掉後便不再消耗電了)。

輸入格式

輸入檔案第一行是兩個數字n和c,n表示路燈的總數,c老張所處位置的路燈號;

接下來n行,每行兩個資料,給出每盞路燈的位置和功率。

輸出格式

乙個資料,即最少的功耗(單位:j,1j=1w·s)。

輸入樣例

5 3

2 10

3 20

5 20

6 30

8 10

輸出樣例

此時關燈順序為3 4 2 1 5,不必輸出這個關燈順序

搜尋題。定義 dfs

(x,n

ow

)dfs(x,now)

dfs(x,

now)

指當前在 x

xx 號燈,已經耗電 now

(j

)now(j)

now(j)

,這樣就很好搜尋了。不過注意一點,每次找只需要找當前節點 x

xx 的左右兩邊就行了,這裡運用的貪心的思想,就是如果去關 x

xx 的非相鄰的燈,一定會經過其中乙個相鄰的燈,這樣倒不如先關那個相鄰的燈,使功耗更少,這樣就可以過了。其實,**中 dfs

dfsdf

s 函式裡的迴圈還可以省掉,不過這樣已經夠了。

當然,此題dp可做。定義 f[i

][j]

[0

]f[i][j][0]

f[i][j

][0]

為關掉 [i,

j]

[i ,j]

[i,j

] 區間的燈,最後在 i

ii 處, f[i

][j]

[1

]f[i][j][1]

f[i][j

][1]

表示關掉 [i,

j]

[i,j]

[i,j

] 區間的燈,最後在 j

jj 處。則

f [i

][j]

[0]=

min⁡

f[i][j][0]=\min \

f[i][j

][0]

=min

f [i

][j]

[1]=

min⁡

f[i][j][1]=\min \

f[i][j

][1]

=min

其中,a[i

]a[i]

a[i]

指第 i

ii 盞路燈的位置,sum

[i

]sum[i]

sum[i]

指區間 [1,

i]

[1,i]

[1,i

] 的功率和,即 sum

[i]=

sum[

i−1]

+sum[i]=sum[i-1]+

sum[i]

=sum

[i−1

]+第i

ii盞燈的功率。

還要注意初始化,一開始將 f[]

[][]

ff[

][] 陣列歸為 +

∞+\infty

+∞,將 f[c

][c]

[0]=

f[c]

[c][

1]=0

f[c][c][0]=f[c][c][1]=0

f[c][c

][0]

=f[c

][c]

[1]=

0 ,c

cc 指一開始的位置,外層 j

jj 從 c

cc 到 n

nn ,內層 i

ii 從 j+1

j+1j+

1 到 1

11 ,依次更新即可。

#include

#include

#include

using

namespace std;

struct node a[55]

;int ans=

0x7fffffff/2

,n,c;

int vis[55]

;//標記有沒有走過

void

dfs(

int x,

int now)

vis[i]=1

;dfs

(i,now+t)

; vis[i]=0

;}i=x-1;

while

(vis[i]

&&i>=

1) i--

;//找左邊

if(i>=1)

vis[i]=1

;dfs

(i,now+t)

; vis[i]=0

;}if(t==

0) ans=

min(ans,now)

;//沒有可找的,說明已經把燈關完了,更新最優值

}int

main()

洛谷 P1220 關路燈

某一村莊在一條路線上安裝了n盞路燈,每盞燈的功率有大有小 即同一段時間內消耗的電量有多有少 老張就住在這條路中間某一路燈旁,他有一項工作就是每天早上天亮時一盞一盞地關掉這些路燈。為了給村里節省電費,老張記錄下了每盞路燈的位置和功率,他每次關燈時也都是盡快地去關,但是老張不知道怎樣去關燈才能夠最節省電...

洛谷 P1220 關路燈

某一村莊在一條路線上安裝了n盞路燈,每盞燈的功率有大有小 即同一段時間內消耗的電量有多有少 老張就住在這條路中間某一路燈旁,他有一項工作就是每天早上天亮時一盞一盞地關掉這些路燈。為了給村里節省電費,老張記錄下了每盞路燈的位置和功率,他每次關燈時也都是盡快地去關,但是老張不知道怎樣去關燈才能夠最節省電...

洛谷 P1220 關路燈

原本想用搜尋先超時一把 然後發現剪枝居然過了 include include include include include include using namespace std int d 10005 記錄燈的功率 int lef,righ,minx int run int x,int y 記錄...