單調佇列優化dp

2022-10-09 01:57:11 字數 1420 閱讀 6219

1.注意:入隊元素1--n,往往要從0開始新增到n+1,以方便計算上1和n的情況

有負數求最大值,初始化dp方程負無窮

dp方程有多種列法,要懂得轉換思路,

草坪(d),f[i][j]既可以表示到i牛已連續修建了j個牛的最值,也可以是到i牛不包含他的最值,第二種就方便列轉移(第一一種應該也可以)

const int n=100000+10;

ll f[n],sum[n];

dequet;

//f[i[j到i頭奶牛,包括他自己已經連續了j頭 奶牛的最大稀鬆率

//f[i表示不選i奶牛的最大效率

int main()

chu("%lld",ans);

return 0;

}2.瑰麗華爾茲。座標dp:f[i][j]到i j位置的最大移動距離

f[t][i][j]表示在第t時刻在第i行第j列所能獲得的最長距離。 

這樣時間複雜度為o(tnm),可以過50%,但對於100%tle且mle。

所以必須優化,首先把時間t換成區間k,

令f[k][i][j]表示在第k段滑行區間中在位置i,j所能獲得最長距離

注意到在第k段時間內只能向某個方向最多走x步(x為區間長度),得到轉移方程

f[k][i][j]=max(f[k-1][i][j],f[k][i*][j*]+dis(i,j,i*,j*))(i*,j*為上乙個合理的位置)

這個做法的時間複雜度是o(kn^3),會超時,需要進一步優化

用單調佇列優化掉內層的乙個n,就可以做到o(kn^2),可以ac

單調佇列優化,如果是向上走就應該從下往上更新,並且先把上乙個狀態dp[x][y]放進佇列再更新dp[x][y]的最值

不然會加重複

const int maxn=200+10;

int n, m, sx, sy, k, ans, dp[maxn][maxn];

int dx[5] = , dy[5] = ;

struct nodeq[maxn]; //q為單調遞減佇列,要存位置資訊用來計算共走了幾步

char mape[maxn][maxn];

void work(int x, int y, int len, int d) //第k個區間的時長為len,方向為d,起點座標x,y

;//維護單調性,把上乙個狀態的dp[x][y]放進去

while(q[tail].pos - q[head].pos > len) head++; //刪除不可能

dp[x][y] = q[head].dp + i - q[head].pos; //最優解是隊首元素+移動距離

ans = max(ans, dp[x][y]); //記錄結果}}

int main()

printf("%d", ans);

return 0;

}

單調佇列 優化DP

佇列元素保持單調遞增 減 而保持的方式就是通過插隊,把隊尾破壞了單調性的數全部擠掉,從而使佇列元素保持單調。單調佇列的作用 優化dp。許多單調佇列優化的dp可以使複雜度直接降維,下面就以最簡單的一道題為例 在某兩座城市之間有 n 個烽火台,每個烽火台發出訊號都有一定代價。為了使情報準確地傳遞,在連續...

單調佇列優化dp

形如f i max wi的問題都可以用單調佇列優化。例題 板題 注意乙個地方 求完所有的f後 ans不是f n 而是後面的一段字尾的f 注意字尾的左端點。很顯然是rmq問題 計算字首和sum i 對於固定的右端點 i,我們想讓答案最大等價於max,可以用個單調佇列維護。但是隨便乙個資料結構直接on ...

DP 單調佇列優化

使用單調佇列優化的題目具有這樣的特點,他需要我們維持一段區間內的某個最優值,這個區間是隨著遍歷的順序變化的,但是其變化一定具有這樣的特性,也即維持的區間左右端點一定是單調遞增的,而不能出現回流的現象,否則我們在維持佇列單調性過程中剪枝的資料可能是新的區間中的最大值。維持區間最優值的方法有很多,例如靜...