單調佇列DP 斜率DP

2022-06-04 03:48:08 字數 1904 閱讀 9214

考慮到知識點是單調佇列,考慮怎麼使用單調佇列

首先說明一點,小天使可以選擇當前時刻鋼琴是否移動(並非一次就要一段時間)

考慮dp方程,由於每次只能走乙個方向,選擇不了,其實就相當於乙個一維的dp了

以往上(北)為例(t為第t段時間)

\[f[t][i][j]=max_

\]\[變形為

\]\[f[t][i][j]=max_+i

\]然後把\(f[t-1][i'][j]-i'\) 扔進單調佇列裡就可以

然後**沒事找事用了提前宣告,不太好看

#include#include#include#define ll long long

using namespace std;

ll xx,yy,n,m,t,f[300][300],dx[5]=,dy[5]=,ans;

char c[300][300];

struct dequeueq[100001];

void dp(ll x,ll y,ll d,ll len);

int main()

} f[xx][yy]=0;

while(t--)

cout<=1&&y>=1;x+=dx[d],y+=dy[d],i++)

}}

很好,咕了一年,讓我們繼續

題目首先,\(n^2\)的做法不難想

暴力列舉現在的點,然後列舉決策點 \(f_i=min(f_j-dis_+w_)\)

然後考慮優化

這裡有個有意思的貪心:

考慮題意,\(a c\)點間距離為\(c^2=(a+b)^2+d^2\)稍作計算就會發現直接走\(a c\)不如順便去一下\(b\)

所以對於每一列,最下面的點必定是最優的(不要忘了\(w\)大於零)

用乙個\(st\)陣列記錄下每一列的最優點在第幾排,設\(f_\)表示走到第\((i,j)\)點的最大收穫

\[f[i][j]=min(f[st[k]][k]-dis(i,j,st[k],k)+w[i][j])

\]時間複雜度變成了\(m^3\)

意識到可以用下單調佇列優化一下

先無視掉第一維,設\(i\)為當前列

設:\[dis_=(i-st[j])

\]\[f[i]=min(f[j]-dis[j]-(i-j)^2)+w[i]

\]若第\(j\)列優於第\(k\)列

\[f[j->i]>f[k->i]

\]\[f[j]-dis[j]-i^2+2*ij-j^2>f[k]-dis[k]-i^2+2*ik-k^2

\]\[f[j]-f[k]-dis[j]+dis[k]-j^2+k^2>2i*(k-j)

\]\[\frac>i

\]顯然是斜率\(dp\)格式,後面就直接套"模板"

#include#include#include#include#define ll long long

#define ld long double

using namespace std;

const ld eps=1e-6;

const ll m=2100;

ll n,m,f[m][m],st[m],w[m][m],q[m],l,r,dis[m];

ll disc(ll x,ll y)

ld k(ll x,ll y)

int main()

f[1][1]=w[1][1],st[1]=1;

w[1][1]=0;

for(ll i=1;i<=m;i++)

for(ll j=1;j<=m;j++)

if(w[i][j])

} }cout<

}

整理 斜率or單調佇列優化dp

題意 求乙個序列的子區間滿足長度大於k且所有數平均值最大 周源 裡的題。之前有人說周源講的是錯的 其實應該是沒什麼問題的 可以o n 求出 不過這題hdu上的資料不知道怎麼了 反正我在網上找的ac 們全都tle。總之 意思明白就好 反正也是入門題 include include include in...

單調佇列 DP

烽火傳遞 description 烽火台又稱烽燧,是重要的防禦設施,一般建在險要處或交通要道上。一旦有敵情發生,白天燃燒柴草,通過濃煙表達資訊 夜晚燃燒乾柴,以火光傳遞軍情。在某兩座城市之間有n個烽火台,每個烽火台發出訊號都有一定的代價。為了使情報準確的傳遞,在m個烽火台中至少要有乙個發出訊號。現輸...

動態規劃 單調斜率優化DP

acwing 1087.修剪草坪 旅行商問題 輸入樣例 641 351 23 輸出樣例 acwing 1087.修剪草坪 動態規劃 f i max f i 1 f i j 1 sum i j sum i f i 表示從前i個中選,且合法的方案數。令x i j,則有 f i min f i 1 f x...