(c ++)如何有效地制作升序(dyn。解决方案)

时间:2016-11-12 09:14:26

标签: c++ algorithm performance

我目前正在尝试制作一个涉及升序的程序。 N代表序列的大小,K代表最大数,例如

输入:2,3

产出:6(1,1 - 1,2 - 1,3 - 2,2 - 2,3 - 3,3)

我当前的代码会输出正确的答案,但需要花费太多时间才能找到正确的答案。什么是最快的解决方案,我如何做动力解决方案?以下是缓慢解决方案的代码:

#include<iostream>
using namespace std;
int n,k,cnt=0,mod=1000000007;
int seq(int n, int k, int first, int depth){
   if(depth > n){
       cnt = cnt + 1;
       return cnt;
   }
   else {
       for(int i=first;i<=k;i++){
            seq(n,k,i,depth+1);
       }
   }
   return cnt;
}
int main()
{
    cin>>n>>k;
    cout<<seq(n,k,1,1)%mod<<"\n";
    return 0;
}

2 个答案:

答案 0 :(得分:1)

我使用动态编程解决了这个问题。

    #include<bits/stdc++.h>
    #define up(j,k,i) for(i=j;i<k;i++)
    #define down(j,k,i) for(i=j;i>k;i--)
    #define pp(n) printf("%lld\n",n)
    #define is(n) scanf("%lld",&n)
    #define ips(n) scanf("%lld",n)
    #define ss(s) scanf("%s",s)
    #define cool 0
    #define pb push_back
    #define mp make_pair
    #define F first
    #define S second
    #define f(i) cout<<i<<endl;
    #define pll pair<lld,lld> 
    #define pi acos(-1)
    #define ds(n,m) scanf("%lld %lld",&n,&m)
    #define ts(n,m,k) scanf("%lld %lld %lld",&n,&m,&k)
    typedef long double ld;
    typedef long long int lld;
    using namespace std;
    const lld M =1e3+7;
    const lld mod=1e9+7;
    const lld infi =LLONG_MAX;
    lld i,j,ans,k,n,x,y,m,mymax=LLONG_MIN,mymin=LLONG_MAX,b,c,z,sum;
    lld dp[M][M],s[M][M];
    int main()
    {
      lld n,k;
      ds(n,k);
      up(1,k+1,i)
      { 
        s[1][i]=1+s[1][i-1];
      }
      up(2,n+1,i)
      {
        up(1,k+1,j)
        {
          s[i][j]=s[i][j-1]+s[i-1][j];

        }
      }
      pp(s[n][k]);

            return 0;
    }

答案 1 :(得分:0)

您可以计算从S(M)范围内的数字M开始的序列1..K

想象一下,你有N个相等数字的序列M, M, M, M, M (N times)

要生成非降序序列,可以使用L = 0..K-M个递增序列成员(以及所有后续数字)。例如,使用两个,您可以生成有效的序列M, M, M+1, M+1, M+2。请注意,有C(L-1, N-1)个变体可以执行此操作(您可以在L-1点之间插入N-1条垂直线... | .. | ..)

所以

   S(M) = Sum{L=0..K-M} (C(L-1,N-1))

   A(N, K) = Sum{M=1..K}(S(M))