日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【POJ - 2373】Dividing the Path(单调队列优化dp)

發布時間:2023/12/10 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【POJ - 2373】Dividing the Path(单调队列优化dp) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題干:

Farmer John's cows have discovered that the clover growing along the ridge of the hill in his field is particularly good. To keep the clover watered, Farmer John is installing water sprinklers along the ridge of the hill.?

To make installation easier, each sprinkler head must be installed along the ridge of the hill (which we can think of as a one-dimensional number line of length L (1 <= L <= 1,000,000); L is even).?

Each sprinkler waters the ground along the ridge for some distance in both directions. Each spray radius is an integer in the range A..B (1 <= A <= B <= 1000). Farmer John needs to water the entire ridge in a manner that covers each location on the ridge by exactly one sprinkler head. Furthermore, FJ will not water past the end of the ridge in either direction.?

Each of Farmer John's N (1 <= N <= 1000) cows has a range of clover that she particularly likes (these ranges might overlap). The ranges are defined by a closed interval (S,E). Each of the cow's preferred ranges must be watered by a single sprinkler, which might or might not spray beyond the given range.?

Find the minimum number of sprinklers required to water the entire ridge without overlap.?

Input

* Line 1: Two space-separated integers: N and L?

* Line 2: Two space-separated integers: A and B?

* Lines 3..N+2: Each line contains two integers, S and E (0 <= S < E <= L) specifying the start end location respectively of a range preferred by some cow. Locations are given as distance from the start of the ridge and so are in the range 0..L.

Output

* Line 1: The minimum number of sprinklers required. If it is not possible to design a sprinkler head configuration for Farmer John, output -1.

Sample Input

2 8 1 2 6 7 3 6

Sample Output

3

Hint

INPUT DETAILS:?

Two cows along a ridge of length 8. Sprinkler heads are available in integer spray radii in the range 1..2 (i.e., 1 or 2). One cow likes the range 3-6, and the other likes the range 6-7.?

OUTPUT DETAILS:?

Three sprinklers are required: one at 1 with spray distance 1, and one at 4 with spray distance 2, and one at 7 with spray distance 1. The second sprinkler waters all the clover of the range like by the second cow (3-6). The last sprinkler waters all the clover of the range liked by the first cow (6-7). Here's a diagram:?

|-----c2----|-c1| cows' preferred ranges|---1---|-------2-------|---3---| sprinklers+---+---+---+---+---+---+---+---+0 1 2 3 4 5 6 7 8The sprinklers are not considered to be overlapping at 2 and 6.

題目大意:

(這個示意圖是真誤導人啊,還是來說說更詳細的題意吧)

在長為L(<=1000000)的草地(可看成一維的線段)上裝噴水頭,噴射是以這個噴水頭為中心,噴水頭的噴灑半徑是可調節的(但是這題的噴水頭只用考慮一個維度的,即不需要看成是個二維平面的一個圓),調節范圍為[A,B](注意這里需要理解成,安裝完畢的噴水頭,噴灑半徑就是個定值了,不能來回改變。換句話說這里可以這么理解,市場中有多種噴水頭,噴水半徑分別是[A,B]中的整數)。要求草地的每個點被且只被一個噴水頭覆蓋。接下來給你N頭牛,給出每頭牛的活動范圍,并且要求在這個活動范圍內只能有一個噴水頭來覆蓋,也就是不能被兩個噴水頭來拼接覆蓋(也就是不能由多個噴頭分段完全覆蓋)。求使用噴水頭的最小數目。(還有個要求,噴水頭不能噴到0~L之外的區域)

解題報告:

注意到因為有“每個點只能被一個噴水頭覆蓋”的限制,所以噴水頭的半徑不是選擇的越大越好。

明確了題意之后我們來考慮簡化一下題目給的信息和要求。

首先我們要把噴頭等價到右端點上,不然沒法做。也就是把以“每個噴水頭可以噴灑到噴水頭為中心的一個雙向區域”的這個信息變成“噴水頭固定放到整個噴灑區域的右端點,也就是每個噴水頭只可以向左噴灑”(這就像是 dp前構造一個貪心的策略一樣,相當于根據題目中這一個? “ 與噴頭放置具體位置無關,只需要關心噴灑區域 ”? 的性質,我們在不改變題目含義的情況下強行加一個條件來方便我們進行處理,這一點技巧很常用)

設dp[i]代表完全覆蓋 0~i 這個區域,需要的最少噴水頭是多少。首先注意到每一個奶牛的區間只能被一個噴頭噴到,而你要進行后面的處理dp[i]如果是合法的,肯定是要由某個合法的dp[j]? ( i - 2*B <= j <= i - 2*A ) 轉移過來。(顯然滿足dp的無后效性性質,這一點就不證明了)

那么現在題目中還剩下一個限制條件我們還沒有用到,那就是每頭牛的活動區域只能用一個噴水頭單獨覆蓋,那么根據我們剛剛的假設:噴頭等價到右端點上,所以對于中間的每一個點都是不需要處理直接dp[]=INF的。(當然雖然dp值不需要處理,但是單調隊列還是要維護的)(這也可見等價轉化這個假設是多么的重要

還有一點是需要注意的,這題因為要求是所有點都要被覆蓋,所以要求合法點一定是偶數點,并且要求題目輸入的L一定是偶數,不然肯定是非法的。所以你在遍歷的時候遇到奇數點可以直接略過了(但是代碼中寫了,主要是因為要處理差分數組的原因),之所以可以直接略過其實是因為,這題不論維護的哪一個信息,其實都和奇數位置的點沒關系,而唯一起作用的地方就是在牛的活動范圍那里,用以判斷接下去的偶數點是否dp[]值需要是非法值。(這題中奇數位置上的點的dp值甚至都不需要去管,因為全程沒用到)

感受dp的奇妙吧!dp經常可以附帶一個附加效果就是可以把非法情況直接給帶出來了,比如這題就不需要取特判-1的情況,而是直接去dp數組中取數就可以了。

至于為什么考慮奇數的點就會WA呢?按理來說dp也是可以處理這種非法情況的呀?但是請考慮這樣一個問題,你的噴灑頭的長度是偶數的(因為乘以2算直徑了嘛)如果你那么用的話,那么隊列中不止會有偶數距離的值,還會存了奇數距離,而奇數距離是非法的!(因為噴灑的直徑肯定是偶數)那么你在單調隊列取值的時候就需要用判斷的方式來得到需要的解了,而不是刻意直接取數就是答案。(我感覺是因為這個原因,當然也可能是其他原因吧,反正奇數的在這個題中本就是卵用沒有呀)

再就是代碼細節比較多,比如維護單調性的時候必須要i-A>=0(別忘等號!因為dp[0]本身就是要用到的合法解),但是維護區域的時候就不需要i-A>=0。

至于為什么需要i-A>=0,還是因為題意:噴泉不能噴出去...比如線段的長度是4..而我手上的噴泉能噴的距離是(2~3)...結果是-1...因為不論我噴泉在0-3的范圍放哪里...所以按照題意應該輸出-1、

還有個問題,為什么這題可以用單調隊列呢?因為A和B都是常數,所以維護的窗口肯定是單調的往后移動的,所以可以這樣。

AC代碼:

#include<cstdio> #include<iostream> #include<algorithm> #include<queue> #include<map> #include<vector> #include<set> #include<string> #include<cmath> #include<cstring> #define F first #define S second #define ll long long #define pb push_back #define pm make_pair using namespace std; typedef pair<int,int> PII; const int MAX = 2e6 + 5; const int INF = 0x3f3f3f3f; int c[MAX]; int n,L,A,B; deque<int> dq; int dp[MAX]; int main() {cin>>n>>L;cin>>A>>B;A*=2,B*=2; for(int s,e,i = 1; i<=n; i++) {scanf("%d%d",&s,&e);s++,e--;c[s]++;c[e+1]--;}dp[0]=0;for(int i = 1; i<=L; i++) {c[i] += c[i-1];if(i & 1) continue;while(dq.size() && dq.front() < i - B) dq.pop_front();if(i-A>=0) {while(dq.size() && dp[dq.back()] > dp[i-A]) dq.pop_back();dq.push_back(i-A); } if(dq.size() && dp[dq.front()] < INF && c[i] == 0) dp[i] = dp[dq.front()]+1;else dp[i] = INF;}if(dp[L] == INF) printf("-1");else printf("%d",dp[L]);return 0 ; }

?

總結

以上是生活随笔為你收集整理的【POJ - 2373】Dividing the Path(单调队列优化dp)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。