嘟嘟嘟
這題大家應該都做過,就是暴力dp+單調佇列優化。
dp方程其實很好想,最初是這樣的:dp[t][i][j]表示時刻\(t\)後,走到\((i, j)\)格仔的最遠路程,於是就有:
\[dp[t][i][j] = max\ + 1
\]但這是\(o(tn ^ 2)\)的,不僅會tle,還能mle。
接著看題,發現給得\(k\)沒用上。想一下發現\(k\)的特點是同一時間區間的移動方向是一樣的,於是我們把第一維改成第\(k\)個時間區間,轉移方程就變成了:
\[dp[k][i][j] = max_ ^ \
\]\(len\)表示區間長度。
方程可能醜了點,但意思就是列舉這個點能在這個時間段內從哪兒轉移過來,然後就是對應的dp值加上這兩點之間的距離。
注意如果有的格仔不能走,就不能從這裡轉移。
複雜度\(o(kn ^ 3)\)。
於是就有單調佇列優化啦。
對於乙個點,這一步能轉移到他的實際上就是x或y方向上連續的一段dp值,於是我們把這些dp值放進單調佇列裡就行了。
這樣優化到\(o(kn ^ 2)\),就過了。
需要注意的是,我們要用k - 1時刻更新k時刻的答案,因此先把dp[x][y]放入佇列,再用隊首更新dp值。這樣就保證了放進去的dp值一定是上乙個時刻的。
#include#include#include#include#include#include#include#include#include#includeusing namespace std;
#define enter puts("")
#define space putchar(' ')
#define mem(a, x) memset(a, x, sizeof(a))
#define in inline
typedef long long ll;
typedef double db;
const int inf = 0x3f3f3f3f;
const db eps = 1e-8;
const int maxn = 205;
inline ll read()
inline void write(ll x)
int n, m, sx, sy, k;
char a[maxn][maxn];
struct node
t[maxn];
int dp[maxn][maxn];
struct que
q[maxn];
int l = 1, r = 0;
const int dx = , dy = ;
in bool check(int x, int y)
in int dis(int xa, int ya, int xb, int yb)
in void solve(int x, int y, int d, int len)
; while(l <= r && dis(x, y, q[l].x, q[l].y) > len) ++l;
dp[x][y] = q[l].val + dis(x, y, q[l].x, q[l].y);
} x += dx[d]; y += dy[d]; }}
int main()
int ans = 0;
for(int i = 1; i <= n; ++i)
for(int j = 1; j <= m; ++j) ans = max(ans, dp[i][j]);
write(ans), enter;
}
NOI 2005 瑰麗華爾茲 DP 單調佇列
time limit 3 sec memory limit 64 mb submit 490 solved 250 submit status discuss 你跳過華爾茲嗎?當 響起,當你隨著旋律滑動舞步,是不是有一種漫步仙境的愜意?眾所周知,跳華爾茲時,最重要的是有好的 但是很少有幾個人知道,世...
2412 NOI2005 瑰麗華爾茲
你跳過華爾茲嗎?當 響起,當你隨著旋律滑動舞步,是不是有一種漫步仙境的愜意?眾所周知,跳華爾茲時,最重要的是有好的 但是很少有幾個人知道,世界上最偉大的鋼琴家一生都漂泊在大海上,他的名字叫丹尼 布德曼 t.d.檸檬 1900,朋友們都叫他1900。1900出生於20世紀的第一年出生在往返於歐美的郵輪...
P2254 NOI2005 瑰麗華爾茲
單調佇列優化線性dp 單調佇列中只需儲存下標 只能優化最內層迴圈 dp c 1 x y dp c 1 x que tl dis x,y,x,que tl 時才將隊尾元素出隊 而不僅僅是dp c 1 x y dp c 1 x que tl 即 用隊中所存下標對應狀態對當前狀態的貢獻為依據選擇是否留在隊...