這道題調了我一天...呃.....開始很多地方沒注意....傳說中樓教主的男人八題搞定一道...
這道題是一道典型的dp題...但直接做時死超的....所以要用單調佇列來優化....關於最基礎的單調佇列...我前一篇文章已經說了..所以直接分析本題..
題意是說有乙個直線的山脊...噴泉是乙個在中間向兩邊同時噴的...最近噴a..最遠b...同時山脊上有牛...每只牛在乙個區域裡活動...牛活動的區域...只能被乙個噴泉的水來覆蓋...求最少的噴泉使山脊上所有地方都能有水澆灌到...
題意要注意 : 噴泉不能噴出去...比如山脊的長度是3..而我手上的噴泉能噴的距離是(2-3)...結果是-1...因為不論我噴泉在0-3的範圍放**...都有水出去..這裡算是trick..
dp思想 :
f[k]代表0-k這塊區域所需最少的噴泉.....注意.同樣計算時要考慮到是正好噴到k!!..噴過k的要不得....
方程就出來了....f[ k ] =min( f [ i ] ) + 1 其中 k-2*b <= i <= k-2*a ...並且 ( i + k ) %2==0 ( i,k同奇偶時..噴泉的水才能正好到k...).....
這裡就是前面 i 個都放好了...然後再在 i - k中放乙個使得這一段全被覆蓋....應該好理解....
再乙個考慮到有牛活動的區域只能有乙個噴泉來覆蓋.....首先將牛按 s優先...e次優先排序...k是從1-l掃瞄整個山脊的..用乙個數g來記錄當前到了第幾個牛區域..g初始為1.當k在掃瞄過程中發現 k > cow[g]. s..也就是邁進了乙個牛活動的區域...那麼中間就不做了..k直接到cow[g].e去....這樣就能保證牛活動區域只有乙個噴泉了...
這個dp演算法沒一點問題....但是會超時...下面加入單調佇列來優化...
單調佇列優化:
從遞迴方程可以看出...每次更新k是要 k-2*b ~ k-2*a內...同奇偶最小的值.....有明顯的單調思想..加入單調佇列維護 k 之前數的單調性...當k<2*a..顯然f[k]一直是沒有辦法設立噴泉...所以這一段都是-1...當k>=2*a了...則每次先將 k-2*b ~ k-2*a入佇列...維護單調後...取直接取隊首更新...這裡如果每次都是放入 k-2*b ~ k-2*a ..那單調佇列就沒有意義了...其實可以記錄上一次已經放到那個數了...這一次接著上一次放就是的....比如用 m 記錄上一次放到哪了...如果一段都是沒牛的山脊...那每一次相當於只要放乙個數去單調佇列中...高效了很多....那為什麼還要用個m來記錄上一次放到哪了而不是不每次就是放乙個數進去?這就是因為考慮進過有牛活動區域的問題...進過牛區域...每次的k就不知是++了...要跳過去一段長度了...所以不能只放乙個了...
這裡還有個問題...要保證 i 與 k 同奇偶...處理這個問題...我開始是更新玩單調佇列後...再從前往後掃..掃到乙個同奇偶的就停下來..用這個數更新...可以過...但很懸....1000ms..有種考試沒幾個...老師實在沒辦法加了幾分正好60的感覺....於是著手優化....
為了保證奇偶...乾脆就開兩個佇列...乙個是偶數字的....乙個是奇數字的...要加入佇列的是偶數字的就加到偶數字的單調佇列中去..是奇數字的就加到奇數字的單調佇列裡去..這樣就省了一大段更新完佇列再從前往後搜同奇偶的過程....
下面就是我優化的巨大成果!! 快了快10倍被有木有!!!!
zzyzzy12
2373
accepted
11920k
125ms
c++1469b
2011-08-25 13:16:24
9227043
zzyzzy12
2373
accepted
8000k
1000ms
c++1580b
2011-08-25 11:50:53
program :
#include#includeusing namespace std;
#define oo 2000000000
struct pp
cow[1001];
int n,l,a,b,q[2][1000001],dp[1000001],k,g,h[2],p[2],m,x;
void updataqueue(int x,int k)
else
if (k<2*a) dp[k]=-1;
else
k++;
}return dp[l];
}bool cmp(pp a,pp b)
{ if (a.s!=b.s) return a.s
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個奶牛的...
poj2373(單調佇列優化dp)
傳送門 題意是每個灑水裝置的半徑範圍為 a,b 每頭奶牛有自己的乙個區間 s,e 這個區間只能由乙個灑水裝置覆蓋。要求整個區間 1,l l 1e6 不重疊的被覆蓋,最少要多少個灑水裝置,灑水裝置的範圍不可以超過整體區間的範圍。因為乙個區間 s,e 只能由乙個灑水裝置覆蓋,所以 s 1,e 1 都不可...