序关系计数问题的两种实现思路:动态规划 & 递推

201 阅读2分钟

问题描述

用关系 " << "和 " == "将3个数 ABCA、B、C依序排列时,有13种不同的序关系: A=B=CA=B<CA<B=CA<B<CA<C<BA=C<BB<A=CB<A<CB<C<AB=C<AC<A=BC<A<BC<B<AA=B=C,A=B<C,A<B=C,A<B<C,A<C<B,A=C<B,B<A=C,B<A<C,B<C<A,B=C<A,C<A=B,C<A<B,C<B<A。若要将 nn 个数依序进行排列,试设计一个算法,计算出有多少种不同的序关系(是计算数目,不是给出各种排列)。要求算法的空间复杂性为 O(n)O(n),时间复杂性为 O(n2)O(n^2)

解决思路

若用 A[i,j]A[i,j] 表示用 jj 个" << "号连接 ii 个数时产生的不同序关系数,并约定当 j>i1j>i-1 时, A[i,j]=0A[i,j]=0 ,另外显然 A[i,0]=1,i[1,n]A[i,0]=1, i\in[1,n]

A[i,j]=(j+1)(A[i1,j1]+A[i1,j])A[i,j]=(j+1)(A[i-1,j-1]+A[i-1,j])

考虑 ii 个数是由 i1i-1 个数增加一个 xx 得到的,则分为两种情况: ①增加 xx 之前有 j1j-1 个 " << " ; ②增加 xx 之前有 jj 个 " << "。另外, xxj+1j+1 种可能性,这是因为,若把相等数视为同一个数,则 jj<<ii 个数的情况为: S1<S2<<Sj+1S_1 < S_2 < \cdots < S_{j+1}

//动态规划法
import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Scanner sc=new Scanner(System.in);
        int n=sc.nextInt();
        int[][] dp=new int[n+1][n+1];
        for(int i=1;i<=n;i++){
            for(int j=0;j<=i-1;j++){
                if(j==0){
                    dp[i][0]=1;
                }else{
                    dp[i][j]=(j+1)*(dp[i-1][j-1]+dp[i-1][j]);
                }
            }
        }
        int sum=0;
        for(int i=0;i<=n;i++){
            sum+=dp[n][i];
        }
        System.out.println(sum);
    }
}
//递推法
int  Orderings( int  n)
 {
    A[0]=1;
    for(int j=1;j<=n-1;j++)
      A[j]=0;
    for(int i=2;i<=n;i++)
      for(int j=i-1;j>=1;j--)
        A[j]=(j+1)*(A[j-1]+A[j]);
    int total=0;
    for(int j=0;j<=n-1;j++)
       total+=A[j];
 return total;
}   
递推法,复杂度不满足题目要求:
简单的说就是:存在K,使得a1=a2=a3=a4...ak<ak+1....an成立。以<为分界线。后面的那一部分是子问题。
选取K个数的组合数为C(n,k)=c(n-1,k-1)+c(n-1,k);
这是高中的知识,就是说n个人中有一个特例,c(n-1,k-1)表示这个人一定在其中,c(n-1,k)表示这个人不选中。
加上后面的子问题退出递推式为g(n),g(n)表示N个数时的序关系数。g(n)=∑C(n,k)*g(n-k)   k from 1 to n。
其实组合问题本来就是一个递归,你要求最后面的值你就得先求前面的值,这也是动态规划的思想之一

递推法代码实现的巧妙之处:代码先计算出 i=2i=2 时对应的 A[j]A[j],当 i=3i=3 时,代码 A[j]=(j+1)(A[j1]+A[j])A[j]=(j+1)*(A[j-1]+A[j])中,右侧 A[j]A[j] 对应的时上一步的结果( i=2i=2 )时,因此得到的当前步( i=3i=3 )的结果,以此类推。