【记忆化搜索】洛谷_3956 棋盘

##题意
给出一个 m ∗ m m*m mm的方格,其中有一些格子上有颜色。我们从(1,1)出发,终点是(n,n)。我们每次要站在有颜色的格子上,如果我们接下来走的格子和现在格子的颜色一致,那么就不用花费金币,如果颜色不一致就要花费1金币,如果没有颜色,可以使用魔法来让这个格子变成任意颜色,花费2金币(不能连续使用魔法)。求走到终点花费的最少金币。
##思路
记忆化搜索。用一个数组记录走到这个格子的最少金币,然后每次搜索时就可以剪枝。搜索按正常的打就好了。
##代码

#include<cstdio>
#include<cstring>
using namespace std;
int m,n,a,b,c,map[105][105],ans[105][105],v[105][105];
short dx[4]={0,0,1,-1},dy[4]={1,-1,0,0};
void dfs(int x,int y,int f,int s)
{
    if (ans[x][y]<=s) return;//剪枝
    ans[x][y]=s;//记录答案
    int xx,yy;
    for (int i=0;i<4;i++)
    {
        xx=x+dx[i];yy=y+dy[i];
        if (!map[xx][yy]&&f||(xx<1||xx>n||yy<1||yy>n)||v[xx][yy]) continue;//不能连续使用魔法,在范围内
        v[xx][yy]=1;
        if (map[xx][yy]==map[x][y]) dfs(xx,yy,0,s);//颜色相同直接走
        else if (!map[xx][yy])//使用魔法
        {
            map[xx][yy]=map[x][y];
            dfs(xx,yy,1,s+2);
            map[xx][yy]=0;
        }
        else dfs(xx,yy,0,s+1);//颜色不同消耗1金币
        v[xx][yy]=0;
    }
}
int main()
{
    memset(ans,127/3,sizeof(ans));
    scanf("%d%d",&n,&m);
    while (m--)
    {
        scanf("%d%d%d",&a,&b,&c);
        map[a][b]=c+1;
    }
    dfs(1,1,0,0);
    if (ans[n][n]==707406378) printf("-1");
    else printf("%d",ans[n][n]);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值