洛谷 P3800 Power收集 題解

2021-10-01 22:53:34 字數 2212 閱讀 5159

題目:p3800 power收集

單調佇列 - dp

考慮 f[i

][j]

f[i][j]

f[i][j

] 表示走到位置(i,

j)

(i,j)

(i,j

)時可以獲得的最大權值

我們發現 f[i

][j]

f[i][j]

f[i][j

] 是由 f[i

][j−

k]∼f

[i][

j+k]

f[i][j-k] \sim f[i][j+k]

f[i][j

−k]∼

f[i]

[j+k

] 和 f[i

−1][

j]

f[i-1][j]

f[i−1]

[j] 轉移過來的

那麼,我們可以用單調佇列維護區間 [j−

k,j+

k]

[j-k,j+k]

[j−k,j

+k] 內 f

ff 的最大值

明白這個後就很簡單了,維護單調遞減佇列並列舉更新就可以了

注意有一點很容易錯:在同一行你只能瞬移一次,並且不能折返

也就是說瞬移的上一步不能還是瞬移,所以要用乙個輔助陣列s

ss

for

(int i=

1;i<=n;

++i)

q.clear()

;for

(int j=

1;j<=k;

++j)

push

(i,j)

;for

(int j=

1;j<=m;

++j)

for(

int j=

1;j<=m;

++j)

f[i]

[j]=

max(f[i]

[j],s[j]);

// 最後合併取最大值

}

完整**:

#include

#include

#include

#include

using

namespace std;

const

int maxn=

4010

,inf=

0x3f3f3f3f

;int f[maxn]

[maxn]

,a[maxn]

[maxn]

;int s[maxn]

;int n,m,k,ans;

deque <

int> q;

inline

intread()

while

(ch>=

'0'&& ch<=

'9')s=

(s<<3)

+(s<<1)

+(ch^48)

,ch=

getchar()

;return s*w;

}void

push

(int i,

int j)

q.push_back

(j);

}void

pop(

int x)

}int

main()

for(

int i=

1;i<=n;

++i)

q.clear()

;for

(int j=

1;j<=k;

++j)

push

(i,j)

;for

(int j=

1;j<=m;

++j)

for(

int j=

1;j<=m;

++j)

f[i]

[j]=

max(f[i]

[j],s[j]);

}for

(int i=

1;i<=m;

++i)

ans=

max(ans,f[n]

[i])

;printf

("%d\n"

,ans)

;return0;

}

洛谷p3800power收集

原題 一道很不錯的優先佇列題 f i j 的最大值由上一行的狀態有關,轉移方程f i j max f i 1 z a i j z j k,j k 每個轉移會超時,所以我們對上一行建立單調佇列,由1推到m,提前入隊,超出範圍出隊。include include include include incl...

洛谷P3800 Power收集

顯然這是一道dp題,樸素演算法很容易想 dp i j v i j max dp i 1 k j t leq k leq j t 然而這樣的轉移是 o nm 2 的,不合要求,還要繼續優化。注意到 k leq 4000 棋盤的資料是相當稀疏的,那麼我們考慮將有p點的格仔當成乙個結點,建圖。根據題意 必...

洛谷 P3800 Power收集

據說在紅霧異變時,博麗靈夢單身前往紅魔館,用十分強硬的手段將事件解決了。然而當時靈夢在power達到max之前,不具有 上線收點 的能力,所以她想要知道她能收集多少p點,然而這個問題她答不上來,於是她找到了學oi的你。可以把遊戲介面理解成乙個n行m列的棋盤,有k個格仔上有p點,其價值為val i,j...