單調佇列優化線性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]]。即:用隊中所存下標對應狀態對當前狀態的貢獻為依據選擇是否留在隊中,而不是所存下標對應狀態的dp值
#include
#include
#include
using
namespace std;
const
int inf=
1e9;
intread()
while
(ch>=
'0'&&ch<=
'9')
return f*x;
}const
int maxn=
205;
int n,m,sx,sy,k;
char ch[maxn]
[maxn]
;int s[maxn]
,t[maxn]
,d[maxn]
,ed,ans;
int dp[maxn]
[maxn]
[maxn]
;int dx[6]
=,dy[6]
=;bool
can1
(int x,
int y)
bool
can2
(int x,
int y)
int que[
40005
],hd,tl;
intdis
(int x,
int y,
int i,
int j)
void
work1
(int c,
int x,
int y)
while
(hd<=tl&&
dis(x,y,que[hd]
,y)>len) hd++;if
(hd<=tl) dp[c]
[x][y]
=dp[c-1]
[que[hd]
][y]
+dis
(x,y,que[hd]
,y);
}else
x+=dx[d[c]
],y+
=dy[d[c]];
}}void
work2
(int c,
int x,
int y)
while
(hd<=tl&&
dis(x,y,x,que[hd]
)>len) hd++;if
(hd<=tl) dp[c]
[x][y]
=dp[c-1]
[x][que[hd]]+
dis(x,y,x,que[hd]);
}else
x+=dx[d[c]
],y+
=dy[d[c]];
}}intmain()
for(
int i=
1;i<=k;i++
) ed=t[k]
;for
(int c=
0;c<=k;c++)}
} dp[0]
[sx]
[sy]=0
;for
(int c=
1;c<=k;c++)if
(d[c]==2
)if(d[c]==3
)if(d[c]==4
)}for(
int i=
1;i<=n;i++)}
printf
("%d\n"
,ans)
;return0;
}
P2254 NOI2005 瑰麗華爾茲
單調佇列優化dp 思路感覺比較簡單,但也許是最近降智嚴重,實現的時候還自閉了一會 kk n,m le 200,k le 200,t le 40000 發現區間個數比較小,可以考慮從 k 開始入手,也就是挨個考慮每個時間區間的情況來轉移 因為每個區間內傾斜方向相同,也就是這段時間內只能往乙個方向走或不...
luoguP2254 NOI2005 瑰麗華爾茲
題目比較好,人比較菜。include define maxn 205 using namespace std int n,m,x,y,k,f maxn maxn maxn l,r,d,dx 7 dy 7 l,r,q maxn ans 0 char tu maxn maxn int main mems...
Luogu 2254 NOI2005 瑰麗華爾茲
簡單dp,設 f 表示第i個時間段,鋼琴處在 j,k 位置移動距離的最大值,那麼有轉移 f max f f max f 其中 j dx len leq a leq j 1 k dy len leq b leq k 1 len ed st 1 其實就是乙個滑動視窗,考慮到轉移順序,就是寫四遍單調佇列 ...