洛谷P1514 引水入城 dfs 區間dp

2021-09-26 09:43:45 字數 1945 閱讀 4272

在乙個遙遠的國度,一側是風景秀美的湖泊,另一側則是漫無邊際的沙漠。該國的行政區劃十分特殊,剛好構成乙個n

nn行×

m\times m

×m列的矩形,如上圖所示,其中每個格仔都代表一座城市,每座城市都有乙個海拔高度。

為了使居民們都盡可能飲用到清澈的湖水,現在要在某些城市建造水利設施。水利設施有兩種,分別為蓄水廠和輸水站。蓄水廠的功能是利用水幫浦將湖泊中的水抽取到所在城市的蓄水池中。

因此,只有與湖泊毗鄰的第1行的城市可以建造蓄水廠。而輸水站的功能則是通過輸水管線利用高度落差,將湖水從高處向低處輸送。故一座城市能建造輸水站的前提,是存在比它海拔更高且擁有公共邊的相鄰城市,已經建有水利設施。由於第n

nn行的城市靠近沙漠,是該國的乾旱區,所以要求其中的每座城市都建有水利設施。那麼,這個要求能否滿足呢?如果能,請計算最少建造幾個蓄水廠;如果不能,求乾旱區中不可能建有水利設施的城市數目。

題解裡面說的是記憶化搜尋啊。但是這道題o(n

3)o(n^3)

o(n3

)完全是可以過的啊。

首先對於第一問,明顯的,只要從第一行每乙個點dfs

dfsdf

s(不直接bfs

bfsbf

s是為了方便第二問),然後到達第n

nn行就記錄一下,最後判斷一下第n

nn行是否全部到達即可。

有乙個很顯然的結論,如果最終是可以到達全部的邊境城市的,那麼任意乙個第一行的城市可以輸水到達的城市均為一段連續的區間。

所以我們在對於每乙個第一行的點進行dfs

dfsdf

s時,記錄下它能輸送到的區間。

然後就是乙個線段覆蓋的裸題了,直接暴力區間dpdp

dp即可。

#include

#include

#include

using

namespace std;

const

int n=

510;

const

int dx=

,dy=

;int n,m,cnt,l[n]

,r[n]

,map[n]

[n],f[n]

[n];

bool vis[n]

[n],flag[n]

;void

dfs(

int x,

int y,

int p)

vis[x]

[y]=1;

for(

int i=

1;i<=

4;i++)if

(map[x]

[y]>map[x+dx[i]

][y+dy[i]])

dfs(x+dx[i]

,y+dy[i]

,p);

}int

main()

for(

int i=

1;i<=m;i++)if

(!flag[i]

) cnt++;if

(cnt)

return

!printf

("0\n%d"

,cnt)

;for

(int i=m;i>=

1;i--

)for

(int j=i;j<=m;j++

)for

(int k=i;k

) f[i]

[j]=

min(f[i]

[j],f[i]

[k]+f[k+1]

[j])

;printf

("1\n%d"

,f[1

][m]);

return0;

}

洛谷 P1514 引水入城(DFS)

注意這道題只能用dfs而不能直接用dp,因為在每乙個格仔,沒有固定的方向,而是上下左右都可以走。但其中有dp的思想 不斷更新l和r。這道題中首先判斷乾旱區所有的城市能否都能建有水利工程。則先讓第一行的每乙個城市都有水利工程,然後進行遍歷,看最後一行的所有點能不能都被走到,如果有走不到的,則說明不行,...

洛谷P1514 引水入城 dfs

題目 搜尋 dp 自己想出來的方法第一次80分好高興!再改了改就a了,狂喜亂舞 也就是 dfs,仔細一想第一行的每個點能覆蓋到最後一行的點一定是連續的一段,否則沒人能覆蓋中間間斷的點 所以最上面每個點跑一遍 dfs,記下能覆蓋區間的 l 和 r,再小小dp一下即可。如下 include includ...

洛谷 P1514 引水入城

題目描述 在乙個遙遠的國度,一側是風景秀美的湖泊,另一側則是漫無邊際的沙漠。該國的行政區劃十分特殊,剛好構成乙個n 行m 列的矩形,如上圖所示,其中每個格仔都代表一座城市,每座城市都有乙個海拔高度。為了使居民們都盡可能飲用到清澈的湖水,現在要在某些城市建造水利設施。水利設施有兩種,分別為蓄水廠和輸水...