问题描述
用关系 " "和 " "将3个数 依序排列时,有13种不同的序关系: 。若要将 个数依序进行排列,试设计一个算法,计算出有多少种不同的序关系(是计算数目,不是给出各种排列)。要求算法的空间复杂性为 ,时间复杂性为 。
解决思路
若用 表示用 个" "号连接 个数时产生的不同序关系数,并约定当 时, ,另外显然 。
考虑 个数是由 个数增加一个 得到的,则分为两种情况: ①增加 之前有 个 " " ; ②增加 之前有 个 " "。另外, 有 种可能性,这是因为,若把相等数视为同一个数,则 个 的 个数的情况为: 。
//动态规划法
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。
其实组合问题本来就是一个递归,你要求最后面的值你就得先求前面的值,这也是动态规划的思想之一
递推法代码实现的巧妙之处:代码先计算出 时对应的 ,当 时,代码 中,右侧 对应的时上一步的结果( )时,因此得到的当前步( )的结果,以此类推。