国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 學(xué)院 > 開(kāi)發(fā)設(shè)計(jì) > 正文

【NOI2005T1】瑰麗華爾茲-DP單調(diào)隊(duì)列優(yōu)化

2019-11-08 02:21:29
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

測(cè)試地址:瑰麗華爾茲

做法:設(shè)f(i,x,y)為第i段時(shí)間之后鋼琴正好滑動(dòng)到第x行第y列的最長(zhǎng)滑動(dòng)距離,很容易想到狀態(tài)轉(zhuǎn)移方程,按照傾斜方向分為四種情況考慮,這里只列出傾斜方向?yàn)?(向上)的情況:f(i,x,y)=max(f(i-1,x+s,y)+s),其中s≤鋼琴與當(dāng)前傾斜方向的反方向上最近的障礙物或者船的邊緣的距離(看上去很繞對(duì)不對(duì)...其實(shí)s就相當(dāng)于鋼琴在這一個(gè)時(shí)間段內(nèi)滑動(dòng)的距離),如果死算時(shí)間復(fù)雜度將是O(n^3*k),難以接受,考慮單調(diào)隊(duì)列優(yōu)化。

還是討論傾斜方向?yàn)?的情況。先將狀態(tài)轉(zhuǎn)移方程變形為f(i,x,y)=max(f(i-1,x+s,y)+(x+s))-x,令k=x+s,則f(i,x,y)=max(f(i-1,k,y)+k)-x,注意到k的取值范圍是單調(diào)遞增的,且f(i-1,k,y)+k為由k可在O(1)時(shí)間內(nèi)確定的常數(shù),滿(mǎn)足單調(diào)隊(duì)列優(yōu)化的性質(zhì),因此可以將時(shí)間復(fù)雜度降低一維,變成O(n^2*k),這樣就可以接受了。對(duì)于其他傾斜方向,用類(lèi)似的方法進(jìn)行分析就可以了。

以下是本人代碼:

#include <cstdio>#include <cstdlib>#include <iostream>#include <algorithm>#define inf 999999999using namespace std;int n,m,x,y,t,f[2][210][210],que[210];char g[210][210];int main(){  scanf("%d%d%d%d%d",&n,&m,&x,&y,&t);  for(int i=1;i<=n;i++)  {    getchar();	for(int j=1;j<=m;j++)	  scanf("%c",&g[i][j]);  }    int now=0,past=1;  for(int i=1;i<=n;i++)    for(int j=1;j<=m;j++)	  if (i==x&&j==y) f[past][i][j]=0;	  else f[past][i][j]=-inf;  for(int i=1,a,b,c;i<=t;i++)  {    scanf("%d%d%d",&a,&b,&c);	int ti=b-a+1,h,t;	switch(c)	{	  case 1:{	           for(int j=1;j<=m;j++)			   {			     h=1,t=0;				 for(int k=n;k>=1;k--)				 {				   if (g[k][j]=='x') h=t+2;				   else				   {				     while(h<=t&&que[h]>k+ti) h++;					 while(h<=t&&f[past][k][j]+k>f[past][que[t]][j]+que[t]) t--;				   }				   que[++t]=k;				   if (h<=t) f[now][k][j]=f[past][que[h]][j]+que[h]-k;				   else f[now][k][j]=-inf;				 }			   }			   break;	         }	  case 2:{	           for(int j=1;j<=m;j++)			   {			     h=1,t=0;				 for(int k=1;k<=n;k++)				 {				   if (g[k][j]=='x') h=t+2;				   else				   {				     while(h<=t&&que[h]<k-ti) h++;					 while(h<=t&&f[past][k][j]-k>f[past][que[t]][j]-que[t]) t--;				   }				   que[++t]=k;				   if (h<=t) f[now][k][j]=f[past][que[h]][j]-que[h]+k;				   else f[now][k][j]=-inf;				 }			   }			   break;	         }	  case 3:{	           for(int j=1;j<=n;j++)			   {			     h=1,t=0;				 for(int k=m;k>=1;k--)				 {				   if (g[j][k]=='x') h=t+2;				   else				   {				     while(h<=t&&que[h]>k+ti) h++;					 while(h<=t&&f[past][j][k]+k>f[past][j][que[t]]+que[t]) t--;				   }				   que[++t]=k;				   if (h<=t) f[now][j][k]=f[past][j][que[h]]+que[h]-k;				   else f[now][j][k]=-inf;				 }			   }			   break;	         }	  case 4:{	           for(int j=1;j<=n;j++)			   {			     h=1,t=0;				 for(int k=1;k<=m;k++)				 {				   if (g[j][k]=='x') h=t+2;				   else				   {				     while(h<=t&&que[h]<k-ti) h++;					 while(h<=t&&f[past][j][k]-k>f[past][j][que[t]]-que[t]) t--;				   }				   que[++t]=k;				   if (h<=t) f[now][j][k]=f[past][j][que[h]]-que[h]+k;				   else f[now][j][k]=-inf;				 }			   }			   break;	         }	}	swap(now,past);  }    int ans=0;  for(int i=1;i<=n;i++)    for(int j=1;j<=m;j++)	  ans=max(ans,f[past][i][j]);    PRintf("%d",ans);    return 0;}


發(fā)表評(píng)論 共有條評(píng)論
用戶(hù)名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 永川市| 怀远县| 遂昌县| 泌阳县| 长阳| 哈密市| 蓬莱市| 永善县| 天津市| 神池县| 光泽县| 新泰市| 进贤县| 抚顺县| 蓬安县| 义马市| 汝城县| 滨州市| 邯郸市| 郸城县| 吴堡县| 拜泉县| 和政县| 鸡西市| 永嘉县| 清丰县| 绥阳县| 徐水县| 军事| 平山县| 松潘县| 邵阳县| 舟曲县| 兴业县| 阜南县| 伊宁市| 介休市| 宜兴市| 东宁县| 道真| 元朗区|