洛谷P1514 引水入城

2022-04-12 01:02:49 字數 1753 閱讀 9009

思路:看完這道題馬上想到: 水只往低處流, 直接把每個蓄水池可以 到達的地方全部搜出來!

首先看不能覆蓋最後一行的情況: 直接從第一行開始 bfs 一遍如果最後一行有走不到的, 統計一下數量直接輸出.

如果可以覆蓋呢? 每個蓄水池走出來的最後一行的點可能是斷斷續續的, 如果要 dp, 狀態就會非常難設定. 如果直接狀壓, 資料範圍 500 ......

實際上上面的情況是不會出現的.

如果乙個蓄水池走出來的點 中間是有乙個點斷開, 那麼這個點對於任意乙個蓄水池來說都是走 不到的. 這會在判斷無解時排除.

為什麼一定走不到?

中間有個點斷開了, 但是兩側都可以流到?

那麼中間這個點一定會高於兩側的點, 並且也高於上面的點. 所以還會有誰會流到它呢?

有了上面這個結論, 對於每乙個蓄水池, 它在最後一行所走出來 的點一定是一段連續的區間. 把這些區間拿出來, 就變成了經典的 線段覆蓋問題. 由於資料範圍很小, o(n2) 的做法也是可行的: 設 dp[i] 為覆蓋 1 到 i 的區間所需要的最少線段數. 把每個區間按照 l, r 雙關鍵字 排序, 列舉區間轉移:

dp[ri]=minli+1

最後,我們可以直接用 dfs + 記憶化找到這些區間,這部分的時間複雜度 o(nm)。

**:

#includeusing

namespace

std;

inline

intread()

c=getchar();

}while

(isdigit(c))

return a*b;

}bool

flag;

intn,m,cnt;

int high[501][501

];bool vis[501][501

];int l[501][501

];int r[501][501

];int x[5]=;

int y[5]=;

inline

void dfs(int nx,int

ny)

if(high[nx+x[i]][ny+y[i]]>=high[nx][ny])

if(!vis[nx+x[i]][ny+y[i]])

l[nx][ny]=min(l[nx][ny],l[nx+x[i]][ny+y[i]]);

r[nx][ny]=max(r[nx][ny],r[nx+x[i]][ny+y[i]]);

}}int

main()

}for(int i=1;i<=m;i++)

for(int i=1;i<=m;i++)

}for(int i=1;i<=m;i++)

}if(flag)

int left=1

;

while(left<=m)

}cnt++;

left=maxright+1

; }

puts("1

");printf("%d

",cnt);

return0;

}

洛谷 P1514 引水入城

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

洛谷 P1514 引水入城

題目概述 給定乙個n m的矩陣,每個格仔代表高度,水只能向低處流。從最上面一排倒水,問最下面一排的每個格仔是否都有水流過。若是,輸出最少需在幾個格仔上倒水,若否,則輸出最下面一排有幾個格仔接不到水。解題思路 可以證明,如果底排每個格仔都有水,那麼從頂部每個格仔倒下的水,在底部形成的一定是乙個連續的區...

洛谷P1514 引水入城

想用搜尋水一水,結果一水就是一下午emmm 用第一層的點去更新其他層的點,並記錄能更新到的最遠的端點,然後下面判斷是否最底層都能到達,都能到達就通過記錄的左右端點來更新,使在最少使用的情況下框到最大的範圍就行了 by acermo include include include include in...