c – 如何在此添加此条件并使其最佳?

问题链接是:
http://codeforces.com/problemset/problem/431/C

Quite recently a creative student Lesha had a lecture on trees. After
the lecture Lesha was inspired and came up with the tree of his own
which he called a k-tree.

A k-tree is an infinite rooted tree where:

  • each vertex has exactly k children;
  • each edge has some weight;
  • if we look at the edges that goes from some vertex to its children (exactly
    k edges), then their weights will equal 1, 2, 3, …, k.

The picture below shows a part of a 3-tree.

07001

As soon as Dima, a good friend of Lesha, found out about the tree, he
immediately wondered: “How many paths of total weight n (the sum of
all weights of the edges in the path) are there, starting from the
root of a k-tree and also containing at least one edge of weight at
least d?”. Help Dima find an answer to his question. As the number of
ways can be rather large, print it modulo 1000000007 (10^9 + 7). (Open
the question link above for a picture of the mentioned tree)

Input
A single line contains three space-separated integers: n, k and
d (1 ≤ n, k ≤ 100; 1 ≤ d ≤ k).

Output
Print a single integer — the answer to the problem modulo
1000000007 (10^9 + 7).

所以,我试图为此开发一个递归解决方案.但是,我无法添加约束以确保至少应存在重量d的边缘.我怎样才能做到这一点?这是我的递归函数:

void calc(int present, int total,int k) // Here, present is initialised to 0.
                                        // total is equal to n that is reqd.
                                        // k is the value in the question
{
    if (total == present)
    {
        ans++;
        ans = ans%val;
        return;
    }
    else
    {
        for ( int i = 1; i <= k; i++ )
        {
            if (present+i <= total)
                return calc(present+i,total,k);
        }
    }
}

最佳答案 只需将以下参数添加到函数中 – d以及是否已达到其中一个边至少为d的约束.

void calc(int present, int total,int k, int d, bool atleastd)
{

将约束更改为仅在atleastd时递增.

    if (total == present && atleastd)
    {
        ans++;
        ans = ans%val;
        return;
    }
    else
    {
        for ( int i = 1; i <= k; i++ )
        {
            if (present+i <= total)

当你递归调用你的函数时,传递之前是否已经实现了atleastd,或者你是否刚满足了这个约束(i> = d).

                calc(present+i,total,k,d,atleastd || i >= d);

另外,我删除了上一行的返回.否则,代码将仅测试1个可能的路径 – 所有权重== 1的路径.

        }
    }
}

我假设ans和val是全局变量,ans是问题的答案,初始化为0,val是模数= 1000000007.

最后,虽然这个解决方案可以解决小的测试用例,其中n <= 15,但是对于n = 100,它将太慢. 为了解决n = 100,我建议学习memoizationdynamic programming.我将把这作为练习留给你.

点赞