数据范围:
m<=100
dfs+剪枝
简单剪枝思路:
如何当前所需要花费的金币数大于已经大于当前走到终点的最小的金币数,就不可能比当还要在少了
dfs采用记录5个变量,分别表示 x坐标,y坐标,花费的钱数,当前格子的颜色,有没有使用魔法......
1 dfs(int x,int y,int cost,int c,int use)
然后判断两个格子的颜色是否相同并且有没有各自是没有颜色.....
---- 如果都有颜色,判断是是否相同
---- 下一步没有颜色就改变颜色
代码:
1 #include<bits/stdc++.h>
2 using namespace std;
3 const int M=100+5;
4 int m,n,col[M][M],val[M][M],vis[M][M],Max=0x3f3f3f3f,x,y,c,xl[5]={0,0,1,-1},yl[5]={1,-1,0,0};
5 void dfs(int x,int y,int cost,int c,int use){
6 if(x<1||x>m||y<1||y>m||cost>=val[x][y])return ;
7 if(x==m&&y==m)Max=min(Max,cost);
8 val[x][y]=cost;
9 for(int i=0;i<4;i++){
10 int dx=x+xl[i],dy=y+yl[i];
11 if(c>=0&&col[dx][dy]>=0)dfs(dx,dy,cost+(c==col[dx][dy]?0:1),col[dx][dy],0);
12 if(c>=0&&col[dx][dy]<0&&use==0)dfs(dx,dy,cost+2,c,1);
13 }
14 }
15 int main(){
16 memset(val,0x3f,sizeof(val));
17 memset(col,-1,sizeof(col));
18 scanf("%d %d",&m,&n);
19 for(int i=1;i<=n;i++){
20 scanf("%d %d %d",&x,&y,&c);
21 col[x][y]=c;
22 }
23 dfs(1,1,0,col[1][1],0);
24 printf("%d\n",Max==0x3f3f3f3f?-1:Max);
25 return 0;
26 }
原文:https://www.cnblogs.com/luogu-yyx/p/9865067.html