2017.6.4 入门组 NO.7——K上升段

Description

对于自然数1..n的一个排列A[1..N] 可以划分为若干个单调递增序列。每个单调递增序列由连续元素A[st..ed]组成,且满足以下条件:
1<=st,ed<=n;
A[i]ed=n 或者 A[ed] > A[ed+1];
  例如:排列1 2 4 5 6 3 9 10 7 8 可划分为3个单调递增序列 1 2 3 4 5 6;3 9 10 ;7 8 ; 所以我们称这是一个 3上升段序列 。
现在给定n和k , 求出n的全排列中的,k上升段序列的个数

Input

输入仅有1行,包含两个数n, k(1 < n < 20, 1 < k < n)。

Output

输出n的所有k上升段的个数。

Sample Input

3 2
Sample Output

4

( 说明,符合条件的排列是132,312,213,231)


设f[i,j]为从1~i分j段符合的排序的个数
这题类似于全排列
每次枚举可以分为多一段和不变两种情况
①j*f[i-1,j]
②(i-j+1)*f[i-1,j-1]


代码如下:

#include <iostream>
using namespace std;
long long f[25][25]; 
int main()
{
    int n,k;
    cin>>n>>k;
    for(int i=1;i<=n;i++)f[i][i]=1;
    for(int i=1;i<=n;i++)
        for(int j=1;j<i;j++)
            f[i][j]=(i-j+1)*f[i-1][j-1]+j*f[i-1][j];
    cout<<f[n][k];
    return 0;
}

转载于:https://www.cnblogs.com/Comfortable/p/8412280.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值