bzoj
luogu
首先有乙個很顯然的\(o(nmt)\)的\(dp\)。
設\(dp[t][i][j]\)表示\(t\)時刻鋼琴移動到\((i,j)\)位置的最長滑動距離。轉移分滑動以及不動兩種,判一下障礙物就可以了。
這樣有50分。
然後發現100%的資料中\(k\le200\),而且在每一段中轉移都是完全一樣的,就考慮把\(o(nmt)\)的複雜度優化到\(o(nmk)\)。
設\(dp[t][i][j]\)表示第\(t\)個時間段末,鋼琴在\((i,j)\)位置的最長滑動距離。以\(d=1\)向上移動為例,這時\(dp[t][i][j]\)應轉移來自\(dp[t-1][i...i+len][j]\),其中\(len\)是這一時間段持續的長度。
分四種情況大力討論一波即可。
單調佇列優化轉移。這是noip2017pj組的t4難度。
#include#include#includeusing namespace std;
int gi()
const int n = 205;
int n,m,x0,y0,k,s[n],t[n],d[n],hd,tl,q[n],dp[n][n][n],ans;
char map[n][n];
int main()
while (hd<=tl&&q[hd]-j>len) ++hd;
if (hd<=tl) dp[i][j][k]=dp[i-1][q[hd]][k]+q[hd]-j;
while (hd<=tl&&dp[i-1][q[tl]][k]+q[tl]<=dp[i-1][j][k]+j) --tl;
q[++tl]=j;}}
if (d[i]==2)
for (int k=1;k<=m;++k)
while (hd<=tl&&j-q[hd]>len) ++hd;
if (hd<=tl) dp[i][j][k]=dp[i-1][q[hd]][k]+j-q[hd];
while (hd<=tl&&dp[i-1][q[tl]][k]-q[tl]<=dp[i-1][j][k]-j) --tl;
q[++tl]=j;}}
if (d[i]==3)
for (int j=1;j<=n;++j)
while (hd<=tl&&q[hd]-k>len) ++hd;
if (hd<=tl) dp[i][j][k]=dp[i-1][j][q[hd]]+q[hd]-k;
while (hd<=tl&&dp[i-1][j][q[hd]]+q[hd]<=dp[i-1][j][k]+k) --tl;
q[++tl]=k;}}
if (d[i]==4)
for (int j=1;j<=n;++j)
while (hd<=tl&&k-q[hd]>len) ++hd;
if (hd<=tl) dp[i][j][k]=dp[i-1][j][q[hd]]+k-q[hd];
while (hd<=tl&&dp[i-1][j][q[tl]]-q[tl]<=dp[i-1][j][k]-k) --tl;
q[++tl]=k;}}
for (int j=1;j<=n;++j)
for (int k=1;k<=m;++k)
dp[i][j][k]=max(dp[i][j][k],dp[i-1][j][k]);
} for (int i=1;i<=n;++i)
for (int j=1;j<=m;++j)
ans=max(ans,dp[k][i][j]);
printf("%d\n",ans);
return 0;
}
BZOJ1499 NOI2005 瑰麗華爾茲
有乙個字元矩陣,表示能走,x 表示不能走,給出起點的座標,起點有一座鋼琴,每單位時間可以移動一格,共有k個時間段,然後再給出每個時間段起始時間和結束時間,以及當前時間段能夠移動的方向。而在某個時間,可以控制鋼琴不動,鋼琴不能走到 x 而且不能走出矩陣 求出鋼琴最多能走多少格 一眼dp題 設f t i...
bzoj1499 NOI2005 瑰麗華爾茲
題目鏈結 給出乙個n m的地圖,剛開始人在 x,y 每次給出一段區間 l,r,t 表示在時間 l,r 內,可以使人向4個方向 t 移動一格。求最大可以移動多少格。考慮每一列 上下移 或者一行 左右移 的情況。以右移為例,我們可以很快列出dp方程 f i x y max f i x y f i 1 x...
bzoj 2005 Noi2010 能量採集
description 棟棟有一塊長方形的地,他在地上種了一種能量植物,這種植物可以採集太陽光的能量。在這些植物採集能量後,棟棟再使用乙個能量匯集機器把這些植物採集到的能量匯集到一起。棟棟的植物種得非常整齊,一共有n列,每列有m棵,植物的橫豎間距都一樣,因此對於每一棵植物,棟棟可以用乙個座標 x,y...