队爷的 Au Plan(dp+单调队列)
隊爺的 Au Plan
【問題描述】
隊爺為了變得越來越神,他給自己制定了 n 個任務,編號為 1,
2,…,n。隊爺在完成這些任務之前有一個初始興奮值 m,每個任務
都有一個難度值 hard[i],且對于任何 i>j,有 hard[i]>hard[j],隊爺
完成第 i 個任務,興奮值至少會減少 hard[i],第 i 任務完成之后,隊
爺會受到鼓舞,興奮值又會增加 s[i],每個任務只完成一次。隊爺可
以一次完成所有剩余的難度值不超過現有興奮度的任務, 這樣只會消
耗那個最大的難度值。現在隊爺想知道完成這 n 個任務之后,他的最
大興奮值為多少。
【輸入文件】
第一行 2 個整數 n,m,如題意。
第二行 n 個整數,第 i 個為 hard[i]。
第三行 n 個整數,第 i 個為 s[i]。
【輸出文件】
一個整數,為完成這 n 個任務之后的最大興奮值。Orz CC 杯 NOIP 模擬賽
5
【輸入樣例】
5 5
2 4 5 7 9
4 4 3 6 5
【輸出樣例】
14
【樣例解釋】
第一次完成前 2 個任務,興奮值為 9;
第二次完成后 3 個任務,興奮值為 14。
【數據規模與約定】
對于 30%的數據,1<=n<=2000
對于另外 20%的數據,所有的 s[i]之和小于 200000;
對于 100%的數據,1<=n<=200000,數據保證所有任務都能完成。
100分算法:對于i狀態,考慮j,k兩個決策,i>k>j且f[j]>hard[i]&&f[k]>hard[i]。若j,k不為前面同一個決策轉移得到,則k的決策層數顯然會更大,即額外消耗更多,所以j優于k;若j,k為前面同一個決策l轉移得到:
f[j]=f[l]-sum[l]+sum[j]-hard[j],f[k]=f[l]-sum[l]+sum[k]-hard[k],
f[j]-f[k]=sum[j]-sum[k]+hard[k]-hard[j],
f[j]-sum[j]-(f[k]-sum[k])=hard[k]-hard[j],
即f[j]-sum[j]> f[k]-sum[k],所以j決策優于k決策,
所以對于每一個狀態i,最小的能夠轉移到i的決策總是最優的,這樣只需要用單調隊列維護決策即可(其實一個指針就OK了),時間復雜度為O(n)。
program df;
var i,j,n,m,y,z,k,t:longint;
x:int64;
a,b,c,f,min:array[0..300000] of longint;
s:array[0..300000] of int64;
begin
assign(input,’plan.in’);
reset(input);
assign(output,’plan.out’);
rewrite(output);
readln(n,m);
for i:=1 to n do
read(a[i]);
readln;
for i:=1 to n do
read(b[i]);
for i:=1 to n do
s[i]:=s[i-1]+b[i];
f[0]:=m; k:=1;
while m>a[k] do
begin
min[k]:=0;
inc(k);
end;
for i:=1 to n do
begin
f[i]:=f[min[i]]+s[i]-s[min[i]]-a[i];
while (f[i]>=a[k]) and (k<=n) do
begin
min[k]:=i;
inc(k);
end;
end;
writeln(f[n]);
close(input);
close(output);
end.
轉載于:https://www.cnblogs.com/Gxyhqzt/p/7784244.html
總結
以上是生活随笔為你收集整理的队爷的 Au Plan(dp+单调队列)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android数据存储五种方式总结
- 下一篇: 怎样cp文件夹时忽略指定的文件夹和文件