题意:如图,把一号车从出口(3,6)弄出去,最少多少步,(10步以上输出-1)
题解:没啥知识含量,就硬模拟,记录压缩状态dp[sta],因为每个车都只会在自己所在的列、行移动,所以压缩是只记录一维就行。每个坐标最多6种情况(其实可以在针对车进行压缩,每个车都是4、5个情况。但是空间已经够了)。所以状态为
6
n
6^n
6n种,n为车的数量。然后就是模拟转移+记忆化搜索。
下面是ac代码:
#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
#include<cmath>
#include<queue>
#include<map>
#include<vector>
#define ll long long
#define llu unsigned ll
using namespace std;
const int N = 12;
const int inf = 0x3f3f3f3f;
struct Node
{
int x, y;
int t, d;
} s[N];
int mp[N][N], su[N][N];
int dp[61000010];
int mx = 0;
int ha(Node * s)
{
int ans = 0;
for (int i = 1; i <= mx; i++)
{
int c;
if (s[i].d == 0)
c = s[i].y;
else
c = s[i].x;
ans = ans * 6 + c - 1;
}
return ans;
}
void rha(int h, Node * je, int vis[][10])
{
for (int i = 0;i<= 6; i++)
for (int j = 0; j<= 6; j++)
vis[i][j] = 0;
int cnt = mx;
while(cnt)
{
int g = h % 6;
je[cnt] = s[cnt];
if (je[cnt].d == 0)
{
je[cnt].y = g + 1;
}
else
{
je[cnt].x = g + 1;
}
vis[je[cnt].x][je[cnt].y] = cnt;
if (je[cnt].d == 1)
{
vis[je[cnt].x-1][je[cnt].y] = cnt;
if (je[cnt].t == 3)
vis[je[cnt].x-2][je[cnt].y] = cnt;
}
else
{
vis[je[cnt].x][je[cnt].y-1] = cnt;
if (je[cnt].t == 3)
vis[je[cnt].x][je[cnt].y-2] = cnt;
}
h /= 6;
cnt--;
}
}
bool che(int x, int y, int vis[][10])
{
return x > 0 && x <= 6 && y > 0 && y <= 6 && vis[x][y] == 0;
}
void tran(Node * g, int i, int flag)
{
if (g[i].d == 0) g[i].y+=flag;
else g[i].x+=flag;
}
void print(int vis[][10])
{
cout << "-----------------" << endl;
for (int i = 1; i <= 6; i++)
{
for (int j = 1; j <= 6; j++)
cout <<vis[i][j] << " ";
cout << endl;
}
}
int ans = 0x3f3f3f3f;
void dfs(int sta, int dep)
{
if (dp[sta]<=dep) return;
dp[sta] = dep;
if (dep + s[1].d - 1 > 10) return;
Node g[10];
int vis[10][10];
rha(sta, g, vis);
//print(vis);
//system("pause");
if ( ( ( g[1].x == 3 && g[1].y == 6) ) )
{
//cout << "sd" << endl;
if(g[1].d == 0)
ans = min(ans, dep);
return;
}
for (int i = 1; i <= mx; i++)
{
if (g[i].d == 0)
{
if ( che(g[i].x, g[i].y - g[i].t , vis) )
{
tran(g, i, -1);
dfs(ha(g), dep+1);
tran(g, i, 1);
}
if ( che(g[i].x, g[i].y+1, vis) )
{
tran(g, i, 1);
dfs(ha(g), dep+1);
tran(g, i, -1);
}
}
else
{
if ( che(g[i].x-g[i].t, g[i].y, vis) )
{
tran(g, i, -1);
dfs(ha(g), dep+1);
tran(g, i, 1);
}
if ( che(g[i].x+1, g[i].y, vis) )
{
tran(g, i, 1);
dfs(ha(g), dep+1);
tran(g, i, -1);
}
}
}
}
int main()
{
//memset(dp,0x3f,sizeof(dp));
for (int i = 1; i <= 6; i++)
{
for (int j = 1; j <= 6; j++)
{
scanf("%d", &su[i][j]);
if (su[i][j] == 0) continue;
s[su[i][j]].x = i, s[su[i][j]].y = j,
mp[i][j] = 1;
if (su[i][j] == su[i][j-1])
s[su[i][j]].d = 0, mp[i][j] += mp[i][j-1];
if (su[i][j] == su[i-1][j])
s[su[i][j]].d = 1, mp[i][j] += mp[i-1][j];
s[su[i][j]].t = mp[i][j];
mx = max(mx, su[i][j]);
}
}
//for(int i=0;i<=mx;i++)
// cout<<s[i].t<<endl;
//for (int i = 1; i <= mx; i++)
// cout << s[i].d << endl;
int g = ha(s);
memset(dp, 0x3f, sizeof(dp));
dfs(g, 1);
int gg = ans + s[1].t-1;
printf("%d\n", gg > 10 ? -1 : gg);
return 0;
}