poj2373(單調佇列優化dp)

2022-05-06 23:24:05 字數 1266 閱讀 8102

傳送門

題意是每個灑水裝置的半徑範圍為[a,b],每頭奶牛有自己的乙個區間[s,e],這個區間只能由乙個灑水裝置覆蓋。

要求整個區間[1,l](l<=1e6)不重疊的被覆蓋,最少要多少個灑水裝置,灑水裝置的範圍不可以超過整體區間的範圍。

因為乙個區間[s,e]只能由乙個灑水裝置覆蓋,所以[s+1,e-1]都不可能是某乙個灑水裝置灑水範圍的右端點。

我們用not_r來打個標記。

看到l的範圍1e6,我們知道應該是使用o(n)的演算法。

設f[i]表示處理到i這個位置需要的灑水裝置個數。(i一定是右端點)。

f[i]=min(f[j])+1(a<=(i-j)/2<=b)

直接迴圈時間o(n^2)考慮優化。

我們發現對於點i,可以用的j一定是一段連續的區間,所以單隊維護最小的f[j]。

因為乙個j能不能被使用還要看它的位置是否滿足限制,所以用佇列id存一下下標。

因為i是右端點,所以在迴圈的時候,我們是偶數個的增加。

#include#include

#include

#define ll long long

#define inf 2100000000

#define n 1000003

#define re register

using

namespace

std;

intread()

while(s>='

0'&&s<='9')

return x*f;

}void print(int

x)int

id[n],f[n],q[n],not_r[n];

intmain()

for(int i=1;i<=l;++i)f[i]=inf;

int h=1,t=0,head=1,tail=0

; id[++t]=0

;

for(int i=2;i<=l;i+=2)//

偶數個的加

while(head<=tail&&(i-q[head])/2>b)head++;

if(head<=tail)

}

if(f[l]!=inf)printf("

%d\n

",f[l]);

else printf("

-1\n");

}/**/

view code

POJ2373 單調佇列優化DP

這道題調了我一天.呃.開始很多地方沒注意.傳說中樓教主的男人八題搞定一道.這道題是一道典型的dp題.但直接做時死超的.所以要用單調佇列來優化.關於最基礎的單調佇列.我前一篇文章已經說了.所以直接分析本題.題意是說有乙個直線的山脊.噴泉是乙個在中間向兩邊同時噴的.最近噴a.最遠b.同時山脊上有牛.每只...

POJ 2373 單調佇列優化DP

題意 思路 f i min f j 1 2 i j 2 i表示當前在第i個點。f i 表示當前最少的線段個數 先是n 2的樸素dp 果斷tle by siriusren include include include using namespace std int n,l,a,b,tot 1,xx,...

POJ 2373 單調佇列優化dp

題目大意 有一塊長度為l的草原,你需要用灑水器把所有草坪都覆蓋並且每塊草坪只能被覆蓋一次,有n個奶牛所在的草坪屬於 l,r 這些區間只能有乙個灑水器 題目解析 定義dp i 為在第i塊草坪結束的時候所蘇姚最少的灑水器,dp i min dp j 1 i 2b j i 2a,還有乙個問題就是n個奶牛的...