題意比較繞,多看兩遍就看懂了
重點在於求滿足要求的情況時的答案
可能也是可想的
注意到對於乙個第一行的點,如果是滿足要求的情況下,
他所能到達的一定是一段連續的區間
考慮如果不連續的話,那一定是繞過了乙個區域,
那這一圈都是可以流過去的,而且這一圈都不能流進這個區域
那他就是乙個不滿足要求的情況
所以對於乙個點,他能給供水的是一段區間
那這就轉化成了乙個線段覆蓋問題
正好之前也沒做過,這裡寫一下:
有兩種寫法,
第一種是貪心:在當前已經選出的區間中找一條左端點在其中,
且右端點最大的線段,之後將這條線段併入已選區間
直至選完
第二種是 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 列的矩形,如上圖所示,其中每個格仔都代表一座城市,每座城市都有乙個海拔高度。為了使居民們都盡可能飲用到清澈的湖水,現在要在某些城市建造水利設施。水利設施有兩種,分別為蓄水廠和輸水站。蓄水廠...