我正在努力解决这个问题,因此,如果有人可以提供帮助,我们将不胜感激。问题是这样的:
计算k人在2 x n矩阵中的坐姿数量(n和k是通过标准输入从用户获得的)。矩阵也由用户提供,可以包含以下字符:“。” -人们可以坐在这里,“#”-人们不能坐在这里。
矩阵中的人不能相邻(也就是说,如果一个人位于(行,列),另一个人不能坐在(行1,列)或(行,列1) -请注意,他们可以坐在(第1行,第1列)上。
例如,如果n = 3,则k = 2并给出以下矩阵:
..#
...
答案是5。在矩阵中容纳2个人的所有可能方法是(u表示一个人坐在该字段上):
u.# .u# ..# u.# .u#
.u. u.. u.u ..u ..u
答案 0 :(得分:0)
让我们从左到右浏览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;
}