CF208B 题解
CF208B 题解
题目分析
这道题是一个策略类问题,用动态规划实现。数据范围
这里使用记忆化搜索实现动态规划。先预处理出所有可以合并的牌,再进行搜索。如果这个状态已经被搜索过,直接返回,否则判断两种操作方法是否能实现,并对下一步的状态进行搜索。
代码
这样说比较抽象,建议结合代码理解。
#include <iostream>
using namespace std;
string s[55];
bool flag[55][55][55][55], poker[55][55];
bool dfs(int x, int x1, int x2, int cnt)
{
if (cnt == 1) // 如果已经合成一堆牌
{
return true; // 直接返回
}
if (flag[x][x1][x2][cnt] == true) // 记忆化,如果这个状态已经被搜索过,返回
{
return false;
}
flag[x][x1][x2][cnt] = true; // 标记这个状态已经被搜索过
bool ans = false;
if (poker[x][x1] == true) // 如果最右边两张牌可以合并
{
ans |= dfs(x, x2, cnt - 3, cnt - 1); // 更新答案
}
if (cnt > 3 && poker[x][cnt - 3] == true) // 如果最后一张牌和倒数第四张牌可以合并
{
ans |= dfs(x1, x2, x, cnt - 1); // 再次更新答案
}
return ans;
}
int main()
{
int n;
cin >> n;
for (int i = 1; i <= n; ++i)
{
cin >> s[i]; // 输入
}
for (int i = 1; i <= n; ++i)
{
for (int j = 1; j <= n; ++j) // 预处理
{
if (s[i][0] == s[j][0] || s[i][1] == s[j][1]) // 如果花色或数值相同
{
poker[i][j] = true; // 标记为 true
}
}
}
if (dfs(n, n - 1, n - 2, n) == true) // 通过记忆化搜索判断是否能够接龙完成
{
cout << "YES"; // 输出答案
}
else
{
cout << "NO";
}
return 0; // 完结撒花!!
}
:::success[你可以] 如果看懂了,就点个赞吧! :::
:::warning[注意] 不要直接复制题解,会棕名的! :::