POJ 1769線段樹維護dp

2021-09-13 23:54:36 字數 2731 閱讀 6662

我們設dp[i][j]為做到第i個sort時候,最大值被移動到j需要轉移用的數目。

dp[i][j]=dp[i-1][j](if(ti!=j) 即移動不到當前最大值

dp[i][j]=min(dp[i-1][j], dp[i-1][k] (si<=k<=ti)+1(if(ti=j))即這個最大值包含在這個區間。

我們發現dp值只與他前乙個有關,故可以開滾動陣列,而且可以知道,以前的狀態是不用清除的,所以直接開一維陣列來滾動即可。

即dp[ti]=min(dp[ti],dp[k] (si<=k<=ti)+1)

這裡我們可以發現了,這麼做其實還是n*m的時間複雜度,不過這種形式我們可以用線段樹來優化,單點更新,dp[ti] ,區間詢問si,ki的最小值,正是線段樹最有用的地方。

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define up(i,a,b) for(int i=a;i#define dw(i,a,b) for(int i=a;i>b;i--)

#define upd(i,a,b) for(int i=a;i<=b;i++)

#define dwd(i,a,b) for(int i=a;i>=b;i--)

//#define local

typedef

long

long ll;

const

double esp =

1e-6

;const

double pi =

acos(-

1.0)

;const

long

long inf =

0x3f3f3f3f

;using

namespace std;

typedef pair<

int,

int> pir;

int n, m;

int tree[

1<<18]

;//log50000*4

int dp[

50005];

int ik[

500005];

int jk[

500005];

void

pushup

(int rt)

//向上推

void

init

(int rt,

int l,

int r)

int mid =

(l + r)

>>1;

init

(rt <<

1, l, mid)

;init

(rt <<1|

1, mid +

1, r)

;pushup

(rt);}

//初始化

void

update

(int jk,

int k,

int l,

int r,

int rt)

if(jk <= mid)

update

(jk, k, l, mid, rt<<1)

;else

update

(jk, k, mid +

1,r, rt <<1|

1);pushup

(rt)

;//向上推,維護區間的最小值

}//更新

intquerry

(int l,

int r,

int rt,

int a,

int b)

//因為可能多個區間都放問了一遍,所以需要一起求最小值

int mid =

(l + r)

>>1;

if(b <= mid)ans =

min(ans,

querry

(l, mid, rt <<

1, a, b));

else

if(a > mid) ans =

min(ans,

querry

(mid +

1, r, rt <<1|

1, a, b));

else ans =

min(ans,

min(

querry

(l, mid, rt <<

1, a, mid)

,querry

(mid +

1, r, rt <<1|

1, mid +

1, b)))

;//注意這種情況要變化a,b的值,因為從中間斷開了

return ans;

}int

main()

upd(i,

1, n)

dp[1]

=0;//初始化

init(1

,1, n)

;update(1

,0,1

, n,1)

;up(i,0

, m)

cout << dp[n]

;//最後輸出最大值n可以達到的最小值

return0;

}

洛谷p1769 DP(線段樹思想)

這題乍一看很嚇人,實則當你去手畫一下比賽過程的時候就可以知道了,假設總人數有8人,1,2 3 4 5 6 7 8.題目說了每一輪都是按編號順序從小到大去比賽的那麼第一輪就是 1,2 3,4 5,6 7,8 這麼個比賽順序,第二輪就是 1,2 的勝利者去比 3,4 的勝利者 另外兩個同理 這個比賽的過...

動態dp 線段樹維護轉移矩陣

背景 czy上課講了新知識,從未見到過,總結一下。所謂動態dp,是在動態規劃的基礎上,需要維護一些修改操作的演算法。這類題目分為如下三個步驟 都是對於常係數齊次遞推問題 1先不考慮修改,不考慮區間,直接列出整個區間的dp方程。這個是基礎,動態dp無論如何還是dp 這一步是一般是重點 2.列出轉移矩陣...

POJ 3170 線段樹優化DP

題意 思路 先搞乙個vector 存以t2結尾的結構體 結構體裡面有開始工作的時間和花費 f i 表示取區間 m,i 的代價 易得f i min f k w,f i t1 k by siriusren include include include include using namespace s...