1

原题请见:http://segmentfault.com/q/1010000002627415

我的答案是用简短的递归来解,后来有空想了想传统 DP 的解法,发现也不难。推导过程如下:

S[0] = 0
S[1] = 1
S[2] = 1,1 | 2
S[3] = 1,2 | 1,1,1 | 2,1 | 3
S[4] = 1,3 | 1,1,2 | 2,2 | 1,2,1 | 1,1,1,1 | 2,1,1 | 3,1 |
       ^^^   ^^^^^^^^^^^   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    S[1] + "3"  S[2] + "2"        S[3] + "1"
...
S[n] = S[n-3] + S[n-2] + S[n-1]
       ^^^^^^   ^^^^^^   ^^^^^^
       S + "3"  S + "2"  S + "1"

公式一出,DP 再无难点。直接根据公式建表,然后返回表尾即可。

cppstd::vector<std::string> step(int n) {
    if (n < 1) return std::vector<std::string>{};
    std::vector<std::vector<std::string>> cache( n > 3 ? n+1 : 4);
    cache[1] = {"1m"};
    cache[2] = {"1m,1m", "2m"};
    cache[3] = {"1m,2m", "1m,1m,1m", "2m,1m", "3m"};
    for (int i = 4; i <= n; ++i) {
        for (const auto& s: cache[i-3])
            cache[i].push_back(s + ",3m");
        for (const auto& s: cache[i-2])
            cache[i].push_back(s + ",2m");
        for (const auto& s: cache[i-1])
            cache[i].push_back(s + ",1m");
    }
    return cache[n];
}

int main()
{
    for (const auto& s : step(4))
        std::cout << s << std::endl;
}

注意:这道题限制要求输出全部结果,这直接导致无论如何优化也只能是指数级的复杂度。故,说 DP 是不严谨的,只是往 DP 的思路上靠罢了。


pezy
3.1k 声望332 粉丝

一个 C++ 程序员