P2254 NOI2005 瑰麗華爾茲

2021-09-10 22:24:46 字數 1976 閱讀 7999

單調佇列優化線性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 其實就是乙個滑動視窗,考慮到轉移順序,就是寫四遍單調佇列 ...