考慮到知識點是單調佇列,考慮怎麼使用單調佇列
首先說明一點,小天使可以選擇當前時刻鋼琴是否移動(並非一次就要一段時間)
考慮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...