BZOJ3205: [Apio2013]机器人
来源:互联网 发布:8路监控网络交换机 编辑:程序博客网 时间:2024/06/05 04:07
卡常卡了好久qwq
可以先用记忆化搜索搜出每个位置往四个方向走会走到哪,注意判走到已经走过的地方避免死循环
f[l][r][i][j]表示在(i,j)合成机器人l~r的最小花费
有
对于第二个转移,我们按长度从小到大dp,处理到f[l,r,i,j]时枚举k就行了
对于第一个转移,本来要用spfa,因为转移的边权都相同,可以bfs
维护两个队列,把初始状态放在第一个队列,拓展出来的状态放进第二个队列,每次取出两个队列的队头比较,用小的去拓展
code:
#include<set>#include<map>#include<deque>#include<queue>#include<stack>#include<cmath>#include<ctime>#include<bitset>#include<string>#include<vector>#include<cstdio>#include<cstdlib>#include<cstring>#include<climits>#include<complex>#include<iostream>#include<algorithm>#define ll long long#define inf 1e9using namespace std;const int maxn = 505;const int maxk = 10;const int maxd = 4;const int dx[] = {-1,0,1,0};const int dy[] = {0,1,0,-1};int n,m,K;// 11 +1 12 -1int a[maxn][maxn];struct point{int x,y;}d[maxn][maxn][maxd],nul;bool v[maxn][maxn][maxd];bool cmp(const int &x,const int &y){ if(!x||!y||x>n||y>m||a[x][y]==-1) return false; return true;}point search(const int x,const int y,int k){ if(v[x][y][k]) return nul; if(d[x][y][k].x) return d[x][y][k]; int tk=k; v[x][y][tk]=true; if(a[x][y]==11) k=(k+1)%maxd; if(a[x][y]==12) k=(k+3)%maxd; int nx=x+dx[k],ny=y+dy[k]; if(!cmp(nx,ny)) d[x][y][tk]=(point){x,y}; else d[x][y][tk]=search(nx,ny,k); v[x][y][tk]=false; return d[x][y][tk];}struct node{int x,y,d;}t[maxn*maxn]; int tp;queue<node>q1,q2; int h1,h2;inline bool cmpt(const node x,const node y){return x.d<y.d;}int f[maxk][maxk][maxn][maxn];char str[maxn];int main(){ nul.x=nul.y=-1; scanf("%d%d%d",&K,&m,&n); for(int i=1;i<=n;i++) { scanf("%s",str); for(int j=1;j<=m;j++) { char cc=str[j-1]; if(cc=='x') a[i][j]=-1; else if(cc=='.') a[i][j]=0; else if(cc=='A') a[i][j]=12; else if(cc=='C') a[i][j]=11; else a[i][j]=cc-'0'; } } for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) for(int k=0;k<maxd;k++) d[i][j][k].x=d[i][j][k].y=0; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { for(int k=0;k<maxd;k++) if(d[i][j][k].x==0) d[i][j][k]=search(i,j,k); } for(int l=1;l<=K;l++) for(int r=1;r<=K;r++) for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) f[l][r][i][j]=-1; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) if(a[i][j]>0&&a[i][j]<10) f[a[i][j]][a[i][j]][i][j]=0; for(int L=1;L<=K;L++) { for(int l=1;l+L-1<=K;l++) { int r=l+L-1; tp=0; for(int k=l;k<r;k++) for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) if(a[i][j]!=-1) { int &tmp=f[l][r][i][j]; if(f[l][k][i][j]!=-1&&f[k+1][r][i][j]!=-1) { int temp=f[l][k][i][j]+f[k+1][r][i][j]; if(tmp==-1||tmp>temp) tmp=temp; } } for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) if(f[l][r][i][j]!=-1) t[++tp]=(node){i,j,f[l][r][i][j]}; sort(t+1,t+tp+1,cmpt); for(int i=1;i<=tp;i++) q1.push(t[i]); h1=h2=inf; if(!q1.empty()) h1=(q1.front()).d; while(h1!=inf||h2!=inf) { if(h1<=h2) { node now=q1.front(); q1.pop(); int x=now.x,y=now.y; if(f[l][r][x][y]==h1) { for(int k=0;k<maxd;k++) if(d[x][y][k].x!=-1) { int nx=d[x][y][k].x,ny=d[x][y][k].y,&kk=f[l][r][nx][ny]; if(kk==-1||kk>h1+1) { kk=h1+1; q2.push((node){nx,ny,kk}); } } } } else { node now=q2.front(); q2.pop(); int x=now.x,y=now.y; if(f[l][r][x][y]==h2) { for(int k=0;k<maxd;k++) if(d[x][y][k].x!=-1) { int nx=d[x][y][k].x,ny=d[x][y][k].y,&kk=f[l][r][nx][ny]; if(kk==-1||kk>h2+1) { kk=h2+1; q2.push((node){nx,ny,kk}); } } } } h1=h2=inf; if(!q1.empty()) h1=(q1.front()).d; if(!q2.empty()) h2=(q2.front()).d; } } } int re=-1; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) if(f[1][K][i][j]!=-1) if(re>f[1][K][i][j]||re==-1) re=f[1][K][i][j]; printf("%d\n",re); return 0;}
阅读全文
0 0
- bzoj3205: [Apio2013]机器人
- BZOJ3205: [Apio2013]机器人
- 【bzoj3205】[Apio2013]机器人 斯坦纳树
- 3205: [Apio2013]机器人
- BZOJ 3205 Apio2013 机器人 斯坦纳树
- bzoj 3205: [Apio2013]机器人 斯坦纳树
- BZOJ 3205 [Apio2013]机器人 斯坦纳树
- bzoj 3205: [Apio2013]机器人 (斯坦纳树)
- 3206: [Apio2013]道路费用
- UOJ#109. 【APIO2013】TASKSAUTHOR
- UOJ 109 [APIO2013]TASKSAUTHOR
- BZOJ3206: [Apio2013]道路费用
- BZOJ 3205 & UOJ 107 [APIO2013]ROBOTS
- [提交答案题] UOJ #109 【APIO2013】TASKSAUTHOR
- 【C++心路历程30】(APIO2013)道路费用
- 机器人
- 机器人
- 机器人
- 小朋友学C++(8):继承
- BZOJ 5085(最大-经典题)
- Android数据库操作—— GreenDao让你的数据操作更简单
- Junit测试出现异常:Exception in thread "main" java.lang.NoSuchMethodError: org.junit.platform.commons.util.
- 小朋友学C++(9):构造函数的默认参数
- BZOJ3205: [Apio2013]机器人
- 指纹识别和人脸识别
- 动态规划之单调队列优化专题
- 用户权限
- 解决输入文字换行的方法:
- MFC 笔记
- JavaScript
- Qt中 QString 和int, char等的“相互”转换,关键是QString.toLocal8Bit().data();(转载)
- lua项目思想日常解读【1】