L i n k Link Link
l u o g u P 3956 luogu\ P3956 luogu P3956
D e s c r i p t i o n Description Description
S a m p l e Sample Sample I n p u t Input Input 1 1 1
5 7
1 1 0
1 2 0
2 2 1
3 3 1
3 4 0
4 4 1
5 5 0
S a m p l e Sample Sample O u t p u t Output Output 1 1 1
8
S a m p l e Sample Sample I n p u t Input Input 2 2 2
5 5
1 1 0
1 2 0
2 2 1
3 3 1
5 5 0
S a m p l e Sample Sample O u t p u t Output Output 2 2 2
-1
H i n t Hint Hint
T r a i n Train Train o f of of T h o u g h t Thought Thought
很简单的想法,就DFS暴力每一种情况
稍微剪枝一下(当前值已经超过最优值)
f
i
j
f_{i\ \ j}
fi j表示从
(
1
,
1
)
(1, 1)
(1,1)点到
(
i
,
j
)
(i,j)
(i,j)点的最少花费
C o d e Code Code
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int ans = 1e9, n, m;
int f[101][101], a[101][101];
int dx[4] = {1, -1, 0, 0};
int dy[4] = {0, 0, 1, -1};
bool check(int x, int y, int p)
{
if (x < 1 || x > m || y < 1 || y > m || (p && a[x][y] == -1)) return 0; // 判断是否出界
//p表示是否使用过魔法,若使用过魔法,且当前格子无色,则无法走下去
return 1;
}
void dfs(int x, int y, int money, int p)//p表示是否可以使用魔法
{
if (money >= f[x][y]) return;
if (x == m && y == m) {
ans = min(ans, money);
return;
}
f[x][y] = money;
for (int i = 0; i < 4; ++i)
{
int xx = x + dx[i];
int yy = y + dy[i];
if (check(xx, yy, p))
{
if (a[xx][yy] == -1)
{
a[xx][yy] = a[x][y];
dfs(xx, yy, money + 2, 1);
a[xx][yy] = -1;
}
else if (a[xx][yy] == a[x][y])
dfs(xx, yy, money, 0);
else if (a[xx][yy] != a[x][y])
dfs(xx, yy, money + 1, 0);
}
}
}
int main()
{
int x, y, c;
scanf("%d%d", &m, &n);
for (int i = 1; i <= m; ++i)
for (int j = 1; j <= m; ++j)
a[i][j] = -1;
memset(f, 0x7f, sizeof(f));
for (int i = 1; i <= n; ++i)
{
scanf("%d%d%d", &x, &y, &c);
a[x][y] = c;
}
dfs(1, 1, 0, 0);
if (ans != 1e9) printf("%d", ans);
else printf("-1");
return 0;
}