【问题标题】:Count Number of ways to reach Nth step using steps of lengths 1,2,3,4,......m.(where m<=n)计数使用长度为 1,2,3,4,......m.(其中 m<=n) 的步骤到达第 N 步的方法数
【发布时间】:2015-08-18 08:06:10
【问题描述】:

我得到了一个编号为 105 的号码 n。我必须找到多种方法,使用长度为 1 or 2 or 3 or.....or m 的步长从地面到达第 nth 步,此处为 m

由于答案可能太大,因此输出它以 109+7 为模。

#include<iostream.h>
using namespace std;

#define ll long long
#define MOD 1000000007

ll countWays_(ll n, ll m){
    ll res[n];
    res[0] = 1; res[1] = 1;
    for (ll i=2; i<n; i++)
    {
       res[i] = 0;
       for (ll j=1; j<=m && j<=i; j++)
         res[i] =(res[i]%MOD+ res[i-j]%MOD)%MOD;
    }
    return res[n-1];
}

ll countWays(ll s, ll m){
    return countWays_(s+1, m);
}
int main (){
    scanf("%lld%lld",&s,&m);
    printf("%lld\n",countWays(s,m));
    return 0;
}

作为O(m*n)的复杂度,我想降低它。

【问题讨论】:

  • 不要使用那个标题...stackoverflow.com/q/31816095/1116364
  • thanx @DanielJour!这真的很有帮助!!
  • 提示:设 f(n, m) 是 {1..m} 中加到 n 的总和数。写出 f 的递归关系。
  • OP,你熟悉动态规划吗?
  • 我正在学习。如果您对此提出建议,我将不胜感激。

标签: c++ algorithm combinations permutation combinatorics


【解决方案1】:

您的内部循环将res[i-1] + res[i-2] + ... + res[i-m] 添加到结果中。

sres 中第一个i 元素的总和。然后你可以简单地将s[i-1] - s[i-m-1] 添加到结果中。

ll countWays_(ll n, ll m){
    ll res[n];
    res[0] = 1; res[1] = 1;
    s[0] = 1; s[1] = 2;
    for (ll i=2; i<n; i++)
    {
       if (i <= m)
           res[i] = s[i-1] % MOD;
       else
           res[i] = (s[i-1] - s[i - m - 1] + MOD) % MOD; 
       s[i] = (s[i-1] + res[i]) % MOD;
    }
    return res[n-1];
}

新的复杂度将是O(n)。您甚至可以将s 作为一个数组去掉,并使用一个变量来进行更多的记账。

【讨论】:

  • 它没有给出想要的结果
  • @waza007 我初始化了s[0] 错误,我现在看到它应该是1。现在给出正确的结果了吗?
  • 和 s[1] 应该是 2。毕竟 thnx @IVlad ....u 帮助我减少了每次无用的计算!非常感谢先生
【解决方案2】:

我认为 use 可以使用变量 Sum 来存储从 i-m+1 到 i 的 res 的总和,如下所示:

ll mod(ll a, ll b){ 
    return (a%b+b)%b; 
}
ll countWays_(ll n, ll m){
    ll res[n],sum;
    res[0] = 1; res[1] = 1;
    sum = res[0] + res[1];
    int head_sum = 0;
    for (ll i=2; i<n; i++)
    {
       if ((i - head_sum) > m) {
            sum=mod((sum- res[head_sum]),MOD);
            head_sum++;
       }  
       res[i] = sum;
       sum = mod((sum% MOD + res[i]% MOD),MOD);
    }
    return res[n-1];
}

【讨论】:

  • srr,我还没试过。对于您的代码:我的想法是将 j 所需的所有值存储在变量中。 (EX m=10,你需要进入第 100 步,你可以从 91,92..99 步到第 100 步,我将所有 res[91]、res[92]..res[100] 存储在 var sum 中,所以f[100] just equal sum) 我看到你的代码,我认为你的代码给出了错误的答案,因为你的 for from 1 then f[100] = f[1]+...f[10]
  • 兄弟,我在编程比赛中运行了我的代码,我必须为 m==3 做这件事。它在那里被接受。所以知道我在我的代码上运行的示例测试得到了正确的结果。我在你的 dat 上尝试的相同测试输入给出了错误的结果!
  • 我已经在一些测试用例中用你的代码测试了这段代码。它可能会返回 % 的负值。我已经修好了。我希望这个新代码是正确的
  • 是的,结果是负面的,因此我觉得如果代码有误。谢谢兄弟!
猜你喜欢
  • 2012-04-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-20
  • 1970-01-01
  • 2016-07-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多