(c++) 如何有效地制作升序(dyn.solution)

Posted

技术标签:

【中文标题】(c++) 如何有效地制作升序(dyn.solution)【英文标题】:(c++) How to effectively make ascending sequences (dyn. solution) 【发布时间】:2016-11-12 09:14:26 【问题描述】:

我目前正在尝试制作一个涉及升序的程序。 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;

【问题讨论】:

在你的递归调用中,返回值会发生什么? 定义“时间太多”。可接受的金额是多少? 1.0 秒是可接受的时间。示例的当前时间是 1.5 您的代码会立即为我运行并显示6。请注意,long long 的使用确实不规范。如果您想要大量数字,也许int64_t 是您的意思?通常递归是解决这类问题的不好方法。不仅简单的循环会有所帮助,而且这里只有两层,而且我敢打赌,你可以用更简单的方式通过代数方式解决这个问题。 我有时间限制问题,而不是内存限制问题,我不知道为什么。长长应该不是问题 【参考方案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;
    

【讨论】:

这也许是最好的解决方案,但看起来太难理解了 我也想问一下,为什么你定义了这么多你甚至不使用的函数?和变量 好的,我把它们拿出来了!感谢您的帮助【参考方案2】:

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

假设您有 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) = SumL=0..K-M (C(L-1,N-1))

   A(N, K) = SumM=1..K(S(M))

【讨论】:

以上是关于(c++) 如何有效地制作升序(dyn.solution)的主要内容,如果未能解决你的问题,请参考以下文章

如何在 c++ 和 java 之间通过 udp 有效发送数据数组

在 C++ 中有效地保存许多连续记录的图像

如何在 C++ 中更有效地只生成这么多排列?

如何有效地将单个对象的多个 C++ 数据成员公开给 QML?

如何有效地将大字符串从 Python 传递到 C++ 扩展方法?

如何有效地为现代 C++ 中指向虚拟基类的指针向量分配空间