動規裡的偏序

2021-05-26 21:40:45 字數 1758 閱讀 1687

動規轉移是往往要滿足一系列條件,其中可能只要滿足單調的偏序關係,因此,在動歸理論複雜度超時時,我們可以將這些偏序關係寫出來,或用資料結構,或用維護斜率等一系列方法來維護這些偏序關係,降低複雜度。

例題:給你乙個長度為n的正整數序列a1,a2…an,你需要踢掉一些數(踢完了以後右邊的數字自動往左補),使得踢完後滿足ai=i的數字盡量多。

很容易想出方程,f[i]:=max+1(f[i]指使a[i]為新序列第a[i]項最多能有幾個數字滿足條件),

偏序關係為:1、i>j

2、a[i]>a[j]

3、i-j>=a[i]-a[j] ——> i-a[i]>=j-a[j]

看起來像是三維偏序,但是,不難看出2、3可推出1,所以我們只需維護2、3的偏序關係

2可以快排初始化,3可以對映乙個座標軸,用線段樹或樹狀陣列在log n時間內完成轉移,題目也就此解決。

雖然,現在我們可以很快構造出演算法,但lmd同學考試時雖然也找出偏序關係,但一直認為是三維偏序,只好裸做。

因此,我們要明確我們要維護什麼,要求什麼,最好是寫出來,探尋內部關係,不能漫無目的想演算法。

var a,b:array[1..100000]of longint;

f:array[1..262144]of longint;

n,ans,m1:longint;

procedure qsort(l,r:longint);

var i,j,x,y,c:longint;

begin

i:=l;j:=r;x:=a[(l+r)>>1];y:=b[(l+r)>>1];

repeat

while (a[i]y)) do inc(i);

while (xb[j])) do dec(j);

if not(i>j) then begin

c:=a[i];a[i]:=a[j];a[j]:=c;

c:=b[i];b[i]:=b[j];b[j]:=c;

inc(i);dec(j)

enduntil i>j;

if i0)and(f[x]>1

endend;

function ask(r:longint):longint;

var l:longint;

begin

l:=1+m1-1;r:=r+m1+1;ask:=0;

while not(l xor r=1) do begin

if l and 1=0 then if f[l+1]>ask then ask:=f[l+1];

if r and 1=1 then if f[r-1]>ask then ask:=f[r-1];

l:=l>>1;r:=r>>1

endend;

procedure origin;

begin

m1:=1;

while m1=a[i] then begin

max:=ask(b[i]-a[i]+1)+1;

change(b[i]-a[i]+1,max);

if max>ans then ans:=max

end;

writeln(ans)

end;

begin

assign(input,'easyiv.in');reset(input);

assign(output,'easyiv.out');rewrite(output);

init;

close(input);close(output)

end.

貪心和動規的difference

很多同學在做動規題的時候,很容易做成貪心,的確,動規和貪心是很相近的,在很多時候,動規和貪心沒有明顯的界限,反而在很多時候,我們需要使用貪心的思想,對動規進行優化,不過這也就導致了很多同學分不清什麼題是動規,什麼題是貪心。現在我們來回憶一下,動規的思想是什麼,以前乙個或者多個狀態的最優值,加上現在這...

動規之 尼克的任務

題目描述 尼克每天上班之前都連線上英特網,接收他的上司發來的郵件,這些郵件包含了尼克主管的部門當天要完成的全部任務,每個任務由乙個開始時刻與乙個持續時間構成。尼克的乙個工作日為 n 分鐘,從第 1 分鐘開始到第 n 分鐘結束。當尼克到達單位後他就開始幹活,公司一共有 k 個任務需要完成。如果在同一時...

尼克的任務(座標型動規)

description 尼克每天上班之前都連線上英特網,接收他的上司發來的郵件,這些郵件包含了尼克主管的部門當天要完成的全部任務,每個任務由乙個開始時刻與乙個持續時間構成。尼克的乙個工作日為 n 分鐘,從第一分鐘開始到第 n 分鐘結束。當尼克到達單位後他就開始幹活。如果在同一時刻有多個任務需要完戍,...