algorithm - 在某些限制条件下让人们就座的方式数量
问题描述
我正在努力解决这个问题,所以如果有人可以提供帮助,我将不胜感激。问题是这样的:
计算 k 人可以坐在 2 xn 矩阵中的方式数(n 和 k 是通过标准输入从用户那里获得的)。该矩阵也由用户给出,可以包含以下字符:'.' - 人们可以坐在这里,'#' - 人们不能坐在这里。
矩阵中的人不能相邻(也就是说,如果一个人位于 (row, column),另一个人不能坐在 (row-1, column) 或 (row, column-1)) - 请注意他们可以坐在(第 1 行,第 1 列)上。
例如,如果 n = 3,k = 2 并给出以下矩阵:
..#
...
答案是 5。在矩阵中让 2 人坐下的所有可能方式是(u 表示一个人坐在那个场地上):
u.# .u# ..# u.# .u#
.u. u.. u.u ..u ..u
解决方案
让我们2 x N
从左到右遍历矩阵。在每一列上,我们只能有 3 个状态:
- 用户处于最高位置
- 用户在底部位置
- 没有用户
因此,在每一步中,我们都可以从之前的状态转移,并且我们需要为每个状态和每个用户数量保留多种方式:
- 状态
Top
可以移动到状态:Bottom
或None
- 状态
Bottom
可以移动到状态:Top
或None
- 状态
None
可以移动到状态:Top
,Bottom
或None
答案是所有K
用户状态的总和。
示例代码:
#include <iostream>
#include <map>
#include <string>
using namespace std;
enum State: int
{
Top, // u
// -
Bottom, // -
// u
None, // -
// -
};
int main()
{
int N, K; cin >> N >> K;
string S[2]; cin >> S[0] >> S[1];
map<State, map<int, int>> prev = { { None, {{0,1}} } };
for (int i = 0; i < N; ++i) {
map<State, map<int, int>> cur;
if (S[0][i] == '.') {
for (auto& w : prev[None]) cur[Top][w.first + 1] += w.second;
for (auto& w : prev[Bottom]) cur[Top][w.first + 1] += w.second;
}
if (S[1][i] == '.') {
for (auto& w : prev[None]) cur[Bottom][w.first + 1] += w.second;
for (auto& w : prev[Top]) cur[Bottom][w.first + 1] += w.second;
}
for (auto& w : prev[None]) cur[None][w.first] += w.second;
for (auto& w : prev[Top]) cur[None][w.first] += w.second;
for (auto& w : prev[Bottom]) cur[None][w.first] += w.second;
swap(cur, prev);
}
cout << (prev[Top][K] + prev[Bottom][K] + prev[None][K]) << endl;
return 0;
}
推荐阅读
- google-sheets - Countif 并在两张纸上查找
- sql-server - `merge` 语句会保证所有插入行的 `default current_timestamp` 列的值相同吗?
- html - 如何在 Aframe(故障)中的平面上加载 gif(具有透明度)?
- c# - GetHashCode 是否保证在对象的生命周期内相同?
- php - 如何在包含重音字母的同时从该正则表达式中排除标点符号?
- python - Python 和 Pandas:从一个数据帧中搜索值以查看它是否包含在另一个数据帧中
- ruby-on-rails - 在 Rails 5 中的 JSON 对象中将一个变量传递给下一个变量
- r - 如何让函数在使用 dplyr 的地方工作?
- c# - 单击 Caliburn Micro 中的背景时,文本框是否会失去焦点?
- sql - 更新表并加入第二个表