CF1065D
如果不喜欢过长代码的看官,请移步其他题解...
这题其实思想极其简单:
棋盘问题常见的算法都比较暴力,常用的有搜索和状压dp
而这道题显然没啥能状压的,所以我们考虑搜索
但是仅仅搜索是不够的,因为有极大的可能搜到死...
所以我们引入记忆化
设状态f[i][j][k][0/1/2]代表目前在点(i,j)处,上一个到达的点(注意是达成要求而非经过)的编号为k,目前的棋子种类为1/2/3时,所需要的最小代价
当然这还不够,我们还要保证在代价最小时更换棋子次数最小,所以我们再用状态g[i][j][k][0/1/2]更新,下标含义与上述相同,表示对应状态所需的最小棋子更换次数
注意优先更新f,在保证f合法的情况下维护g
然后用bfs更新即可
#include <cstdio> #include <cmath> #include <cstring> #include <cstdlib> #include <iostream> #include <algorithm> #include <queue> #include <stack> #include <map> #include <string> #include <vector> #include <ctime> #include <set> #include <deque> #include <bitset> using namespace std; int dp[15][15][105][3]; int g[15][15][105][3]; int xp[105],yp[105]; int maps[15][15]; int dir[8][2]={{1,2},{2,1},{2,-1},{-1,2},{-1,-2},{-2,-1},{1,-2},{-2,1}}; int n; bool check(int x,int y) { if(x>0&&x<=n&&y>0&&y<=n) { return 1; } return 0; } void bfs() { memset(dp,0x3f,sizeof(dp)); memset(g,0x3f,sizeof(g)); dp[xp[1]][yp[1]][1][0]=0;//车 dp[xp[1]][yp[1]][1][1]=0;//马 dp[xp[1]][yp[1]][1][2]=0;//象 g[xp[1]][yp[1]][1][0]=0; g[xp[1]][yp[1]][1][1]=0; g[xp[1]][yp[1]][1][2]=0; queue <int> Qx,Qy,Qz,Qv; for(int i=0;i<=2;i++) { Qx.push(xp[1]); Qy.push(yp[1]); Qz.push(i); Qv.push(1); } while(!Qx.empty()) { int ux=Qx.front(); int uy=Qy.front(); int uz=Qz.front(); int uv=Qv.front(); Qx.pop(); Qy.pop(); Qz.pop(); Qv.pop(); if(uv==n*n) { continue; } if(uz==0) { for(int i=1;i<=n;i++) { if(i==uy) { continue; } if(maps[ux][i]==uv+1) { if(dp[ux][i][uv+1][uz]>dp[ux][uy][uv][uz]+1) { dp[ux][i][uv+1][uz]=dp[ux][uy][uv][uz]+1; g[ux][i][uv+1][uz]=g[ux][uy][uv][uz]; Qx.push(ux); Qy.push(i); Qz.push(uz); Qv.push(uv+1); }else if(dp[ux][i][uv+1][uz]==dp[ux][uy][uv][uz]+1&&g[ux][i][uv+1][uz]>g[ux][uy][uv][uz]) { g[ux][i][uv+1][uz]=g[ux][uy][uv][uz]; Qx.push(ux); Qy.push(i); Qz.push(uz); Qv.push(uv+1); } }else { if(dp[ux][i][uv][uz]>dp[ux][uy][uv][uz]+1) { dp[ux][i][uv][uz]=dp[ux][uy][uv][uz]+1; g[ux][i][uv][uz]=g[ux][uy][uv][uz]; Qx.push(ux); Qy.push(i); Qz.push(uz); Qv.push(uv); }else if(dp[ux][i][uv][uz]==dp[ux][uy][uv][uz]+1&&g[ux][i][uv][uz]>g[ux][uy][uv][uz]) { g[ux][i][uv][uz]=g[ux][uy][uv][uz]; Qx.push(ux); Qy.push(i); Qz.push(uz); Qv.push(uv); } } } for(int i=1;i<=n;i++) { if(i==ux) { continue; } if(maps[i][uy]==uv+1) { if(dp[i][uy][uv+1][uz]>dp[ux][uy][uv][uz]+1) { dp[i][uy][uv+1][uz]=dp[ux][uy][uv][uz]+1; g[i][uy][uv+1][uz]=g[ux][uy][uv][uz]; Qx.push(i); Qy.push(uy); Qz.push(uz); Qv.push(uv+1); }else if(dp[i][uy][uv+1][uz]==dp[ux][uy][uv][uz]+1&&g[i][uy][uv+1][uz]>g[ux][uy][uv][uz]) { g[i][uy][uv+1][uz]=g[ux][uy][uv][uz]; Qx.push(i); Qy.push(uy); Qz.push(uz); Qv.push(uv+1); } }else { if(dp[i][uy][uv][uz]>dp[ux][uy][uv][uz]+1) { dp[i][uy][uv][uz]=dp[ux][uy][uv][uz]+1; g[i][uy][uv][uz]=g[ux][uy][uv][uz]; Qx.push(i); Qy.push(uy); Qz.push(uz); Qv.push(uv); }else if(dp[i][uy][uv][uz]==dp[ux][uy][uv][uz]+1&&g[i][uy][uv][uz]>g[ux][uy][uv][uz]) { g[i][uy][uv][uz]=g[ux][uy][uv][uz]; Qx.push(i); Qy.push(uy); Qz.push(uz); Qv.push(uv); } } } if(dp[ux][uy][uv][1]>dp[ux][uy][uv][uz]+1) { dp[ux][uy][uv][1]=dp[ux][uy][uv][uz]+1; g[ux][uy][uv][1]=g[ux][uy][uv][uz]+1; Qx.push(ux); Qy.push(uy); Qz.push(1); Qv.push(uv); }else if(dp[ux][uy][uv][1]==dp[ux][uy][uv][uz]+1&&g[ux][uy][uv][1]>g[ux][uy][uv][uz]+1) { g[ux][uy][uv][1]=g[ux][uy][uv][uz]+1; Qx.push(ux); Qy.push(uy); Qz.push(1); Qv.push(uv); } if(dp[ux][uy][uv][2]>dp[ux][uy][uv][uz]+1) { dp[ux][uy][uv][2]=dp[ux][uy][uv][uz]+1; g[ux][uy][uv][2]=g[ux][uy][uv][uz]+1; Qx.push(ux); Qy.push(uy); Qz.push(2); Qv.push(uv); }else if(dp[ux][uy][uv][2]==dp[ux][uy][uv][uz]+1&&g[ux][uy][uv][2]>g[ux][uy][uv][uz]+1) { g[ux][uy][uv][2]=g[ux][uy][uv][uz]+1; Qx.push(ux); Qy.push(uy); Qz.push(2); Qv.push(uv); } }else if(uz==1)//马 { for(int i=0;i<8;i++) { int tx=ux+dir[i][0]; int ty=uy+dir[i][1]; if(tx<=0||tx>n||ty<=0||ty>n) { continue; } if(maps[tx][ty]==uv+1) { if(dp[tx][ty][uv+1][1]>dp[ux][uy][uv][1]+1) { dp[tx][ty][uv+1][1]=dp[ux][uy][uv][1]+1; g[tx][ty][uv+1][1]=g[ux][uy][uv][1]; Qx.push(tx); Qy.push(ty); Qv.push(uv+1); Qz.push(1); }else if(dp[tx][ty][uv+1][uz]==dp[ux][uy][uv][uz]+1&&g[tx][ty][uv+1][uz]>g[ux][uy][uv][uz]) { g[tx][ty][uv+1][uz]=g[ux][uy][uv][uz]; Qx.push(tx); Qy.push(ty); Qz.push(uz); Qv.push(uv+1); } }else { if(dp[tx][ty][uv][1]>dp[ux][uy][uv][1]+1) { dp[tx][ty][uv][1]=dp[ux][uy][uv][1]+1; g[tx][ty][uv][1]=g[ux][uy][uv][1]; Qx.push(tx); Qy.push(ty); Qv.push(uv); Qz.push(1); }else if(dp[tx][ty][uv][uz]==dp[ux][uy][uv][uz]+1&&g[tx][ty][uv][uz]>g[ux][uy][uv][uz]) { g[tx][ty][uv][uz]=g[ux][uy][uv][uz]; Qx.push(tx); Qy.push(ty); Qz.push(uz); Qv.push(uv); } } } if(dp[ux][uy][uv][0]>dp[ux][uy][uv][uz]+1) { dp[ux][uy][uv][0]=dp[ux][uy][uv][uz]+1; g[ux][uy][uv][0]=g[ux][uy][uv][uz]+1; Qx.push(ux); Qy.push(uy); Qz.push(0); Qv.push(uv); }else if(dp[ux][uy][uv][0]==dp[ux][uy][uv][uz]+1&&g[ux][uy][uv][0]>g[ux][uy][uv][uz]+1) { g[ux][uy][uv][0]=g[ux][uy][uv][uz]+1; Qx.push(ux); Qy.push(uy); Qz.push(0); Qv.push(uv); } if(dp[ux][uy][uv][2]>dp[ux][uy][uv][uz]+1) { dp[ux][uy][uv][2]=dp[ux][uy][uv][uz]+1; g[ux][uy][uv][2]=g[ux][uy][uv][uz]+1; Qx.push(ux); Qy.push(uy); Qz.push(2); Qv.push(uv); }else if(dp[ux][uy][uv][2]==dp[ux][uy][uv][uz]+1&&g[ux][uy][uv][2]>g[ux][uy][uv][uz]+1) { g[ux][uy][uv][2]=g[ux][uy][uv][uz]+1; Qx.push(ux); Qy.push(uy); Qz.push(2); Qv.push(uv); } }else if(uz==2) { for(int i=1;i<=n;i++) { int tx=ux+i; int ty=uy+i; if(check(tx,ty)) { if(maps[tx][ty]==uv+1) { if(dp[tx][ty][uv+1][2]>dp[ux][uy][uv][2]+1) { dp[tx][ty][uv+1][2]=dp[ux][uy][uv][2]+1; g[tx][ty][uv+1][2]=g[ux][uy][uv][2]; Qx.push(tx); Qy.push(ty); Qv.push(uv+1); Qz.push(2); }else if(dp[tx][ty][uv+1][uz]==dp[ux][uy][uv][uz]+1&&g[tx][ty][uv+1][uz]>g[ux][uy][uv][uz]) { g[tx][ty][uv+1][uz]=g[ux][uy][uv][uz]; Qx.push(tx); Qy.push(ty); Qz.push(uz); Qv.push(uv+1); } }else { if(dp[tx][ty][uv][2]>dp[ux][uy][uv][2]+1) { dp[tx][ty][uv][2]=dp[ux][uy][uv][2]+1; g[tx][ty][uv][2]=g[ux][uy][uv][2]; Qx.push(tx); Qy.push(ty); Qv.push(uv); Qz.push(2); }else if(dp[tx][ty][uv][uz]==dp[ux][uy][uv][uz]+1&&g[tx][ty][uv][uz]>g[ux][uy][uv][uz]) { g[tx][ty][uv+1][uz]=g[ux][uy][uv][uz]; Qx.push(tx); Qy.push(ty); Qz.push(uz); Qv.push(uv+1); } } } tx=ux+i; ty=uy-i; if(check(tx,ty)) { if(maps[tx][ty]==uv+1) { if(dp[tx][ty][uv+1][2]>dp[ux][uy][uv][2]+1) { dp[tx][ty][uv+1][2]=dp[ux][uy][uv][2]+1; g[tx][ty][uv+1][2]=g[ux][uy][uv][2]; Qx.push(tx); Qy.push(ty); Qv.push(uv+1); Qz.push(2); }else if(dp[tx][ty][uv+1][uz]==dp[ux][uy][uv][uz]+1&&g[tx][ty][uv+1][uz]>g[ux][uy][uv][uz]) { g[tx][ty][uv+1][uz]=g[ux][uy][uv][uz]; Qx.push(tx); Qy.push(ty); Qz.push(uz); Qv.push(uv+1); } }else { if(dp[tx][ty][uv][2]>dp[ux][uy][uv][2]+1) { dp[tx][ty][uv][2]=dp[ux][uy][uv][2]+1; g[tx][ty][uv][2]=g[ux][uy][uv][2]; Qx.push(tx); Qy.push(ty); Qv.push(uv); Qz.push(2); }else if(dp[tx][ty][uv][uz]==dp[ux][uy][uv][uz]+1&&g[tx][ty][uv][uz]>g[ux][uy][uv][uz]) { g[tx][ty][uv][uz]=g[ux][uy][uv][uz]; Qx.push(tx); Qy.push(ty); Qz.push(uz); Qv.push(uv); } } } tx=ux-i; ty=uy+i; if(check(tx,ty)) { if(maps[tx][ty]==uv+1) { if(dp[tx][ty][uv+1][2]>dp[ux][uy][uv][2]+1) { dp[tx][ty][uv+1][2]=dp[ux][uy][uv][2]+1; g[tx][ty][uv+1][2]=g[ux][uy][uv][2]; Qx.push(tx); Qy.push(ty); Qv.push(uv+1); Qz.push(2); }else if(dp[tx][ty][uv+1][uz]==dp[ux][uy][uv][uz]+1&&g[tx][ty][uv+1][uz]>g[ux][uy][uv][uz]) { g[tx][ty][uv+1][uz]=g[ux][uy][uv][uz]; Qx.push(tx); Qy.push(ty); Qz.push(uz); Qv.push(uv+1); } }else { if(dp[tx][ty][uv][2]>dp[ux][uy][uv][2]+1) { dp[tx][ty][uv][2]=dp[ux][uy][uv][2]+1; g[tx][ty][uv][2]=g[ux][uy][uv][2]; Qx.push(tx); Qy.push(ty); Qv.push(uv); Qz.push(2); }else if(dp[tx][ty][uv][uz]==dp[ux][uy][uv][uz]+1&&g[tx][ty][uv][uz]>g[ux][uy][uv][uz]) { g[tx][ty][uv][uz]=g[ux][uy][uv][uz]; Qx.push(tx); Qy.push(ty); Qz.push(uz); Qv.push(uv); } } } tx=ux-i; ty=uy-i; if(check(tx,ty)) { if(maps[tx][ty]==uv+1) { if(dp[tx][ty][uv+1][2]>dp[ux][uy][uv][2]+1) { dp[tx][ty][uv+1][2]=dp[ux][uy][uv][2]+1; g[tx][ty][uv+1][2]=g[ux][uy][uv][2]; Qx.push(tx); Qy.push(ty); Qv.push(uv+1); Qz.push(2); }else if(dp[tx][ty][uv+1][uz]==dp[ux][uy][uv][uz]+1&&g[tx][ty][uv+1][uz]>g[ux][uy][uv][uz]) { g[tx][ty][uv+1][uz]=g[ux][uy][uv][uz]; Qx.push(tx); Qy.push(ty); Qz.push(uz); Qv.push(uv+1); } }else { if(dp[tx][ty][uv][2]>dp[ux][uy][uv][2]+1) { dp[tx][ty][uv][2]=dp[ux][uy][uv][2]+1; g[tx][ty][uv][2]=g[ux][uy][uv][2]; Qx.push(tx); Qy.push(ty); Qv.push(uv); Qz.push(2); }else if(dp[tx][ty][uv][uz]==dp[ux][uy][uv][uz]+1&&g[tx][ty][uv][uz]>g[ux][uy][uv][uz]) { g[tx][ty][uv][uz]=g[ux][uy][uv][uz]; Qx.push(tx); Qy.push(ty); Qz.push(uz); Qv.push(uv); } } } } if(dp[ux][uy][uv][0]>dp[ux][uy][uv][uz]+1) { dp[ux][uy][uv][0]=dp[ux][uy][uv][uz]+1; g[ux][uy][uv][0]=g[ux][uy][uv][uz]+1; Qx.push(ux); Qy.push(uy); Qz.push(0); Qv.push(uv); }else if(dp[ux][uy][uv][1]>dp[ux][uy][uv][uz]+1&&g[ux][uy][uv][0]>g[ux][uy][uv][uz]+1) { g[ux][uy][uv][0]=g[ux][uy][uv][uz]+1; Qx.push(ux); Qy.push(uy); Qz.push(0); Qv.push(uv); } if(dp[ux][uy][uv][1]>dp[ux][uy][uv][uz]+1) { dp[ux][uy][uv][1]=dp[ux][uy][uv][uz]+1; g[ux][uy][uv][1]=g[ux][uy][uv][uz]+1; Qx.push(ux); Qy.push(uy); Qz.push(1); Qv.push(uv); }else if(dp[ux][uy][uv][1]==dp[ux][uy][uv][uz]+1&&g[ux][uy][uv][1]>g[ux][uy][uv][uz]+1) { g[ux][uy][uv][1]=g[ux][uy][uv][uz]+1; Qx.push(ux); Qy.push(uy); Qz.push(1); Qv.push(uv); } } } } int main() { scanf("%d",&n); for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { scanf("%d",&maps[i][j]); xp[maps[i][j]]=i; yp[maps[i][j]]=j; } } bfs(); int ans=0x3f3f3f3f; int ret=0x3f3f3f3f; for(int i=0;i<=2;i++) { if(ans>dp[xp[n*n]][yp[n*n]][n*n][i]) { ans=dp[xp[n*n]][yp[n*n]][n*n][i]; ret=g[xp[n*n]][yp[n*n]][n*n][i]; }else if(ret>g[xp[n*n]][yp[n*n]][n*n][i]&&ans==dp[xp[n*n]][yp[n*n]][n*n][i]) { ret=g[xp[n*n]][yp[n*n]][n*n][i]; } } printf("%d %d\n",ans,ret); return 0; }