P3956 棋盘 (DFS)

链接: 原题链接

输入输出样例
输入 #1
5 7
1 1 0
1 2 0
2 2 1
3 3 1
3 4 0
4 4 1
5 5 0
输出 #1
8
输入 #2
5 5
1 1 0
1 2 0
2 2 1
3 3 1
5 5 0
输出 #2
-1

说明/提示

输入输出样例 1 说明

输入输出样例 2 说明

思路讲解

本题与“回家”题十分相似,都是最短路的拓展类型。
本题要求的是花费的最少金币。思路比较容易,根据每一格子的颜色往下搜索即可。但是要注意剪枝,不然会TLE。

代码实现

#include<bits/stdc++.h>
using namespace std;
const int MAXN=105;
int m,n;
int flag,sum;
int a[MAXN][MAXN],v[MAXN][MAXN],f[MAXN][MAXN];
int minn=0x3f3f3f3f;
int dx[4]={1,0,-1,0};
int dy[4]={0,1,0,-1};
void DFS(int x,int y,int sum,bool frog);//走到某个位置(包括这个位置)已经花费了多少 
//frog 为 true 则已经使用过魔法 
int main()
{
	scanf("%d%d",&m,&n);
	int ti,tj,c;
	memset(a,-1,sizeof(a));
	memset(v,0,sizeof(v));
	memset(f, 0x7f, sizeof(f));
	for(int i=1;i<=n;i++)
	{
		scanf("%d%d%d",&ti,&tj,&c);
		a[ti][tj]=c;	
	}
	v[1][1]=1;
	DFS(1,1,0,false);
	if(flag)printf("%d",minn);
	else printf("-1"); 
}
void DFS(int x,int y,int sum,bool frog)
{
	if(x==m&&y==m)
	{
		flag=1;
		if(sum<minn)
			minn=sum;
		return;
	}
	if(sum>minn) return;//剪枝
	if(sum>=f[x][y])return;	 //储存最优解 
	else f[x][y]=sum;
	int tx,ty;
	for(int i=0;i<=3;i++)
	{
		tx=x+dx[i];
		ty=y+dy[i];
		if(tx<1||tx>m||ty<1||ty>m)continue;//防止越界 
		
		
		if(a[tx][ty]!=-1&&v[tx][ty]==0)//下一格有颜色 
		{
			if(a[tx][ty]==a[x][y])
			{
				v[tx][ty]=1;
				DFS(tx,ty,sum,false);
				v[tx][ty]=0;
			}
			if(a[tx][ty]!=a[x][y]) 
			{
				v[tx][ty]=1;
				DFS(tx,ty,sum+1,false);
				v[tx][ty]=0;	
			}
		}
		else //无颜色
		{
			if(!frog&&v[tx][ty]==0)
			{
				v[tx][ty]=1;
				a[tx][ty]=a[x][y]; //使用魔法后将无色格子的颜色变为与上一格子相同的颜色
				DFS(tx,ty,sum+2,true);
				v[tx][ty]=0;
				a[tx][ty]=-1; //回溯时复原无色格子 
			}
		} 
	}
}

继续加油!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值