百度笔试 不等式数列

度度熊最近对全排列特别感兴趣,对于1到n的一个排列,度度熊发现可以在中间根据大小关系插入合适的大于和小于符号(即 ‘>’ 和 ‘<’ )使其成为一个合法的不等式数列。但是现在度度熊手中只有k个小于符号即(‘<”)和n-k-1个大于符号(即’>’),度度熊想知道对于1至n任意的排列中有多少个排列可以使用这些符号使其为合法的不等式数列。
输入描述:
输入包括一行,包含两个整数n和k(k < n ≤ 1000)
输出描述:
输出满足条件的排列数,答案对2017取模。
输入: 5 2
输出: 66

一、暴力解不可行
n的范围为1000,全排列,在逐个去检查小于号有多少个,不可行
二、动态规划
dp(n,k)从dp(n-1, k)和dp(n-1,k-1)状态变化过来
具体递推公式 dp(i,j)表示0~i个数进行全排列,j表示j个小于符号。
dp(i,j) = dp(i-1,j-1)(i-j) +dp(i-1,j) (j+1)
i-j表示,在0到(i-1)中有j-1个小于符号,所以有i-j-1个大于符号(i-1个数说明有i-2个符号),将最后一个数i放在排列的开头也只增加了一个大于号
j+1同理,有j个小于符号,再加将i放在最右边
代码如下:

import java.util.ArrayList;
import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        while (scanner.hasNext()){
            int n = scanner.nextInt();
            int k = scanner.nextInt();
            long[][] dp = new long[n+1][n+1];
            if (n == 1){
                System.out.println(1);
                break;
            }
            dp[1][0] = 1;
            dp[2][0] = 1;
            dp[2][1] = 1;
            for (int i = 3; i <= n; i++) {
                for (int j = 0; j < i; j++) {
                    if (j == 0){
                        dp[i][j] = 1;
                    }
                    else {
                        dp[i][j] = (dp[i-1][j-1]*(i-j) + dp[i-1][j]*(j+1))%2017;
                    }
                }
            }
            System.out.println(dp[n][k]);
            break;
        }
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值