AC代码如下:
#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
int s[105][105];
int color1[105][105];
int f[105][105];
int c1[4]={1,-1,0,0};
int c2[4]={0,0,1,-1};
int m,n;
int maxn=INF;
void dfs(int x,int y,int color,int sum)
{
if(x<1||x>m||y<1||y>m||color1[x][y]||sum>=f[x][y])return;
if(x==m&&y==m)
{maxn=min(maxn,sum);return;}
f[x][y]=sum;
if(s[x][y]==0)
{
for(int i=0;i<4;i++)
{
if(s[x+c1[i]][y+c2[i]]!=0&&!color1[x+c1[i]][y+c2[i]])
{
if(s[x+c1[i]][y+c2[i]]==color)
{
color1[x][y]=1;
dfs(x+c1[i],y+c2[i],color,sum);
color1[x][y]=0;
}
else
{
color1[x][y]=1;
dfs(x+c1[i],y+c2[i],s[x+c1[i]][y+c2[i]],sum+1);
color1[x][y]=0;
}
}
}
}
else
{
for(int i=0;i<4;i++)
{
if(s[x+c1[i]][y+c2[i]]==0&&!color1[x+c1[i]][y+c2[i]])
{
color1[x][y]=1;
dfs(x+c1[i],y+c2[i],s[x][y],sum+2);
color1[x][y]=0;
}
else if(!color1[x+c1[i]][y+c2[i]])
{
if(s[x+c1[i]][y+c2[i]]!=color)
{
color1[x][y]=1;
dfs(x+c1[i],y+c2[i],s[x+c1[i]][y+c2[i]],sum+1);
color1[x][y]=0;
}
else
{
color1[x][y]=1;
dfs(x+c1[i],y+c2[i],s[x+c1[i]][y+c2[i]],sum);
color1[x][y]=0;
}
}
}
}
}
int main()
{
ios::sync_with_stdio(false);
int x,y,c;
cin>>m>>n;
for(int i=1;i<=m;i++)
for(int j=1;j<=m;j++)
f[i][j]=INF;
for(int i=1;i<=n;i++)
{
cin>>x>>y>>c;
s[x][y]=c+1;
}
dfs(1,1,s[1][1],0);
if(maxn==INF)cout<<"-1"<<endl;
else cout<<maxn<<endl;
return 0;
}
初解此题就把他定性位dfs+优化,但交了一发后还是TLE了,然后对比大佬的代码,发现问题在于我剪枝剪的不够好。
核心步骤就是建立一个记忆数组 f ,若在某时刻的sum大于等于f之前存储的数,就直接剪去。
这里要注意等于原来的数也要剪掉,因为如果相等的话就像相当于重回上次经过这个点的时刻了,重复了。