題目傳送門
看起來是差分約束,但是usaco出題人又卡spfa了!
這裡有一種巧妙的dp方法。
f [i
]f[i]
f[i]
: ii
i必須放,最多能放多少個.
考慮上乙個可以放在**。
l [i
]l[i]
l[i]
: 完全在i
ii左邊的區間,左端點的最大值 (不能不放)
r [i
]r[i]
r[i]
: 包含i
ii的區間中,左端點的最小值−1-1
−1(只能放1
11個)
這個怎麼求呢?
給乙個區間[x,
y]
[x,y]
[x,y
],用x−1
x-1x−
1去更新r[y
]r[y]
r[y]
,用x
xx去更新l[y
+1
]l[y+1]
l[y+1]
。最後l
ll取字首最大值,r
rr取字尾最小值。
(這個具體原因可以根據l,r
l,rl,
r的定義思考一下)
於是:f[i
]=ma
x(f[
j])+
1,l[
i]≤j
≤r[i
]f[i]=max(f[j])+1,l[i]\leq j \leq r[i]
f[i]=m
ax(f
[j])
+1,l
[i]≤
j≤r[
i]考慮到l,r
l,rl,
r陣列滿足單調性,可以使用單調佇列優化(線段樹優化應該也行)
#include
#include
using std :: max;
using std :: min;
const
int n =
200010
;int n, m, ans;
int l[n]
, r[n]
, f[n]
;//l(i):完全在i左邊的區間,左端點的最大值 (不能不放)
//r(i):包含i的區間中,左端點的最小值-1 (只能放1個)
intmain()
for(
int i = n; i; i --
) r[i]
=min
(r[i]
, r[i +1]
);for(
int i =
1; i <= n; i ++
) l[i]
=max
(l[i]
, l[i -1]
);static
int hd =
0, bk =
1, q[n]
=, j =1;
for(
int i =
1; i <= n +
1; i ++
)for
(; hd < bk && q[hd]
< l[i]
;++ hd)
; f[i]
= hd < bk ? f[q[hd]]+
1:-1
;if(~ f[i]
) ans =
max(ans, f[i]);
}printf
("%d\n",(
~ f[n +1]
)? f[n +1]
-1:-
1);return0;
}
USACO1 3修理牛棚
題目 問題 b 修理牛棚 時間限制 1 sec 記憶體限制 128 mb 提交 39 解決 5 提交 狀態 討論版 命題人 201805050252 題目描述 在乙個暴風雨的夜晚,農民約翰的牛棚的屋頂 門被吹飛了。好在許多牛正在度假,所以牛棚沒有住滿。剩下的牛乙個緊挨著另乙個被排成一行來過夜。有些牛...
USACO1 3 修理牛棚 Barn Repair
首先給出 m,s,c表示有m根木棍,s個棚,以及c頭牛 接下來有c個數,分別代表每頭牛在哪個棚子裡 要求你用m根棍子 連續的一段長度 覆蓋所有的牛所在的棚子,輸出m根棍子最小的長度和 做法 首先是貪心思想,因為有c個座標必須覆蓋在m個連續長度之下,那麼我們只要把相鄰的兩個點合併 c m 次,那麼每次...
USACO13OPEN 重力異常
船長正在拯救她的船員,beefalo 博士。和所有偉大的冒險故事一樣,這個故事也是發生在乙個2d平面上的。囧 這個平面是m n的格仔組成的網格,代表著船長的世界的乙個側檢視。有些格仔是空的,另一些則是實心的,並且不能直接通過。很不幸的是,船長跳不起來。她必須遵守這個世界的特殊物理法則。1 如果船長的...