P3956 棋盘

P3956 棋盘

题解

注释都在代码里了

       这道题可以用DFS做,记忆化搜索,维护一个money[ ][ ] 表示到达当前节点的最小花费

       不需要记录VIS,因为有一个最小值判断,如果走重复的话一定会得到一个更大的花费,那就直接退出了 

 

 

代码

#include<bits/stdc++.h>

using namespace std;

int m,n;
int clor[105][105],money[105][105];
//clor是记录颜色的数组 ,0无色,1红色,2黄色
//money是记录走到(x,y)的最少花费 
int dx[4]={-1,0,0,1},dy[4]={0,-1,1,0};
int x,y,c;
bool flag=0;  //判断有无解 

bool pan(int x,int y)
{
    return x>=1&&x<=m&&y>=1&&y<=m;
}

void dfs(int x,int y,int step,bool use)
//走到了(x,y),话费为step,use表示是否使用了魔法 
{
    if(!pan(x,y)) return;  //不合法直接退出 
    if(step>=money[x][y]) return ;
//最小值判断
//如果走到(x,y)的花费比之前搜到的结果还大,那么直接退出 money[x][y]=step; //更新成更小花费 if(x==m&&y==m) { flag=1; return; }//有解 for(int i=0;i<=3;i++) //四连通深搜 { int xx=x+dx[i],yy=y+dy[i]; if(pan(xx,yy)) //新节点合法 { if(clor[xx][yy]!=0) //新节点有颜色 { if(clor[xx][yy]==clor[x][y]) //新节点与原来节点同色 dfs(xx,yy,step,0); else //新节点与原来节点不同色 dfs(xx,yy,step+1,0); } else if(!use) //新节点无色,没有使用过魔法,可以使用魔法 { clor[xx][yy]=clor[x][y]; //暂时变色 dfs(xx,yy,step+2,1); clor[xx][yy]=0; //回溯 } } } } int main() { scanf("%d%d",&m,&n); memset(money,0x3f,sizeof(money)); //初始化极大值 for(int i=1;i<=n;i++) { scanf("%d%d%d",&x,&y,&c); clor[x][y]=c+1; } dfs(1,1,0,0); if(flag==1) { printf("%d\n",money[m][m]); } else { printf("-1\n"); } return 0; }

 

转载于:https://www.cnblogs.com/xiaoyezi-wink/p/11113931.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值