題目^o^
pro在一年前贏得了小鎮的最佳草坪比賽後,tw 變得很懶,再也沒有修剪過草坪。現在,新一輪的最佳草坪比賽又開始了,tw 希望能夠再次奪冠。然而,tw 的草坪非常髒亂,因此,tw 只能夠讓他的奶牛來完成這項工作。tw 有 n(1 <= n <= 100,000)只排成一排的奶牛,編號為 1...n。每只奶牛的效率是不同的,奶牛 i 的效率為 e_i(0 <= e_i <= 1,000,000,000)。
靠近的奶牛們很熟悉,因此,如果 tw 安排超過 k 只連續的奶牛,那麼,這些奶牛就會罷工去開派對:)。因此,現在 tw 需要你的幫助,計算 tw 可以得到的最大效率,並且該方案中沒有連續的超過 k 只奶牛。
input
第一行:空格隔開的兩個整數 n 和 k
第二到 n+1 行:第 i+1 行有乙個整數 e_i
output
乙個值,表示 tw 可以得到的最大的效率值。
sample input
5 2123
45sample output
12data range
30% 的資料, n<=100
100% 的資料, n<=100000
隨便說說版:剛剛才弄懂題目是什麼意思qwq看來還是沒有融會貫通"要揣測出題人的意圖"這句話
或者說我語文太差了(這確實是乙個事實)
正解:f[i] 表示安排前 i 個奶牛所獲得的最大值若i>k 那麼 i-k ~ i 中至少有乙個不選
不選的點為 j 即為斷點
然後進入dp常規套路 列舉階段 列舉斷點 轉移
但是這樣子會超時 開o2也超時qwq 我們不得不想想優化
單調佇列優化:
發現我們列舉斷點就是為了求出 f[j-1]-s[j] 的最大值
而 j 是一格一格往右移的 所以想到了滑動視窗
然後 沒了
這裡再講一下滑動視窗: q[i]: 是單調佇列 p[i]:是單調佇列中 i 號元素在原來序列裡的下標當要加入乙個新的元素 y 的時候 先使隊尾比 y 小的元素出隊( tail-- )
因為這些元素在有生之年已經沒有機會成為最大的了
(單調佇列中的元素要成為最大元素,只有當比它大的元素都退休(滑出了視窗外)才行,現在來了乙個比它大還比它年輕的元素,它自然沒機會了)
y 入隊
然後把滑出視窗外的元素彈出( head++ ) p 陣列就是用於這一步
就可以啦
40~80分 code
1 #include2 #include3aacc code#define ll long long
4#define go(i,a,b) for(register int i=a;i<=b;i++)
5using
namespace
std;
6int read() //
cannot read "-"711
return
x;12
}13 ll n,k,head=1,tail=1,a[100010],s[100010],f[100010],q[100010*2],p[100010*2
];14 ll find(int x) //
這裡是單調佇列優化 ! ! !
1522
intmain()
2330 printf("
%lld
",f[n]);
31return0;
32 }
2202 修剪草坪
在一年前贏得了小鎮的最佳草坪比賽後,約翰變得懶惰了,再也沒有修剪過草坪。現在,新一輪的比賽又開始了,約翰希望能夠再次奪冠。然而,約翰家的草坪非常髒亂,因此,約翰需要讓他的奶牛來完成這項工作。約翰家有n頭奶牛,排成一直線,編號為1到n。每只奶牛的能力是不同的,第i頭奶牛的能力為ei。靠在一起的奶牛很熟...
小學期 修剪草坪
有乙個n m的草坪 1 n,m 100 草坪中的草原來的高度都是100。現在使用割草機修剪草坪,來得到各種各樣的圖案。割草機只 能橫著或者豎著割草。每次割草都會先設定乙個高度,割完之後會把比設定高度高的草都割成設定的高度。比如草原來是5 2 8,設定高度為4,那麼割完之後就變成了4 2 4。現在給出...
修剪草坪 單調佇列
這道題我們可以換乙個角度思考,把題意看成 我們找到哪些奶牛不選,且滿足每兩個相鄰的不選的奶牛之間不能間隔超過k,當這些不選的奶牛的貢獻總和最低時,我們選的奶牛貢獻就最高了!這個過程用單調佇列優化一下即可,然而博主太弱了,就用了個優先佇列 include include include include...