• Gym


    题目链接

    题目大意

      你可以将一个排列的前k个数字按升序排序,有多少种长度为n的排列满足其的lis的长度至少为n-1。

    解题思路

      将原来的排列按升序排序。然后通过置换其中的数来考虑方案数。
      首先如果前面k个数字都是1-k,那么后面n-k个数字的lis的长度只要不小于n-k-1就行了,而n-k个数字lis长度为n-k的只有1种,长度为n-k-1的有((n-k-1)^2)种。
      第二种情况是对于一个前k个数字都是1-k的排列,从前面k个数字中任意取出一个数字放到后面n-k个数字后面,这样如果排列的lis的长度为n-1的话,后面n-k个数字必须都是升序排列的,所以就有(k imes (n-k))种。
      第三种情况和第二种类似,这次是从后面n-k个数字中取出一个放到前面k个里头,排好之后就只能放在第k个位置,而且必须后面n-k个数字是按升序排列的才可以,这样的情况一共有n-k种。但是有一种情况重复了,如果把n-k个数字中的第一个数字放到第k个位置的话,和把第k个数字插入到第n-k个数字后面的情况其实是一样的,还要减一,所以方案数是n-k-1。
      因为之前的情况都是考虑前k个已经排好的情况下,因为我们能对前k个排序,前k个数字可以是任意顺序,所以总的方案数就是把上面的所有情况加起来乘上(k!)

    代码

    int main() {	
    	int __; cin >> __;
    	int kase = 1;
    	while(__--) {
    		ll n, k, q; cin >> n >> k >> q;
    		ll f = 1;
    		k = min(n, k);
    		for (ll i = 1; i<=k; ++i) f = f*i%q;
    		ll ans = f*((1 + (n-k-1)*(n-k-1)%q + k*(n-k)%q+ n-k-1)%q)%q;
    		printf("Case #%d: %lld
    ", kase++, ans);
    	}
    	return 0;
    } 
    
  • 相关阅读:
    leetcode78 Subsets
    leetcode76 Minimum Window Substring
    leetcode73 Set Matrix Zeroes
    leetcode70 Climbing Stairs
    leetcode50 Pow(x, n)
    leetcode49 Group Anagrams
    leetcode48 Rotate Image
    正则表达式及字符处理
    RPM软件包管理.作业
    yum管理RPM包.作业
  • 原文地址:https://www.cnblogs.com/shuitiangong/p/14465591.html
Copyright © 2020-2023  润新知