Luogu1514 引水入城

2022-07-24 00:12:27 字數 1447 閱讀 3948

題意比較繞,多看兩遍就看懂了

重點在於求滿足要求的情況時的答案

可能也是可想的

注意到對於乙個第一行的點,如果是滿足要求的情況下,

他所能到達的一定是一段連續的區間

考慮如果不連續的話,那一定是繞過了乙個區域,

那這一圈都是可以流過去的,而且這一圈都不能流進這個區域

那他就是乙個不滿足要求的情況

所以對於乙個點,他能給供水的是一段區間

那這就轉化成了乙個線段覆蓋問題

正好之前也沒做過,這裡寫一下:

有兩種寫法,

第一種是貪心:在當前已經選出的區間中找一條左端點在其中,

且右端點最大的線段,之後將這條線段併入已選區間

直至選完

第二種是 dp:f[i] 表示到第 i 個位置最少用 f[i] 條線段覆蓋

轉移顯然是從一段的最小轉移,由於要保證最小,

就用線段樹維護區間最小就行了

轉移的位置只要保證能跟之前的拼起來就行

由於比較懶就寫了貪心。。。

需要注意的是貪心的話你要保證跟之前區間接起來的話,是已選區間右端點 + 1就行

**:

#include #include #include #include #include #include #include using namespace std;

const int maxn = 505, maxm = 505;

struct pos

};struct line

bool operator < (const line& b) const

inline void update(line val)

return;

}}line[maxn][maxm], myb[maxm];

int n, m, totok;

int dx = , dy = ;

int mp[maxn][maxm];

bool vis[maxn][maxm];

queueq;

inline void chk()

while (!q.empty())

} return;

}line dfs(pos cur, pos frm)

for (int i = 0; i < 4; ++i)

return line[cur.x][cur.y];

}inline void getans()

curitv.r = curmax;

++ans;

} printf("1\n%d\n", ans);

return;

}int main()

if (gg)

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

dfs(pos(1, i), pos(0, 0));

getans();

return 0;

}

luogu1514 引水入城

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

P1514 引水入城

先用dfs搜尋,從最上面的一行往下拓展,所有點拓展完後,掃瞄最後一行是否有沒被染上色的,有則說明 不能滿足要求 如果沒有,在用dfs,計算出最上面一行的每個點 大於等於兩邊的點 能拓展到的最左端和最右端,然後就轉化成了區間覆蓋問題。區間覆蓋問題是給你幾個區間,然後給你乙個大區間,用盡量少的小區間來覆...

P1514 引水入城

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