zoukankan      html  css  js  c++  java
  • Insertion Sort Gym

    题目:题目链接

    题意:对长为n的1到n的数列的前k个数排序后数列的最长上升子序列长度不小于n-1的数列的种数,训练赛时怎么都读不明白这个题意,最后还是赛后问了旁队才算看懂,英语水平急需拯救55555

    思路:明白题意后就很容易了,有一个坑点是k可能比n大,所以我们对k取min(k, n),我们先不考虑前k个数的顺序,比k大的数只能有一个出现在前k个数中,而且是要替换k这个位置的数字,并且最后这个数还要不计入最长上升子序列,可以理解为删掉,如果k + 1存在的话对于这个数要特殊处理,这样后面的那些数必须保证直接是有序的才可以满足题目要求,这种情况有n - k种,如果前k个数最大的数才是k,那么后面的数我们可以选一个不考虑这个数的顺序(最后删掉这个数),组成的种类为1 + (n - k)*(n - k - 1),其中1是每一个数都在排好序的位置上的情况,这里拿出来防止重复计数,对于我们刚刚提到的k + 1存在的情况下,这时我们可以选一个比k小的数来替换,因为最后可以不删掉k + 1而是删掉选定的那个比k小的数。最后,因为前k个数是会排序的,所以我们再乘一个k!就OK啦。

      所以:ans = n - k + 1 + (n - k) * (n - k - 1),如果k + 1存在的话,ans += (k - 1) * (n - k)

    AC代码(临近java考试先用java写一段时间代码了5555):

    import java.util.Scanner;
    
    public class Main {
    
        public static void main(String[] args) {
            Scanner in  = new Scanner(System.in);
    
            long T, n, k, mod;
            T = in.nextLong();
            for(long t = 1; t <= T; ++t) {
                n = in.nextLong();
                k = in.nextLong();
                mod = in.nextLong();
    
                k = Math.min(n, k);
                long ans = n - k + 1 + (n - k) * (n - k - 1);
                if(k < n)
                    ans += (k - 1) * (n - k);
                for(long i = 1; i <= k; ++i)
                    ans = ans * i % mod;
                System.out.println("Case #" + t + ": " + ans);
            }
    
            in.close();
        }
    }
  • 相关阅读:
    LeetCode 258. Add Digits
    LeetCode 257. Binary Tree Paths
    LeetCode 周赛 184
    js算法初窥05(算法模式02-动态规划与贪心算法)
    js算法初窥04(算法模式01-递归)
    js算法初窥03(搜索及去重算法)
    js算法初窥02(排序算法02-归并、快速以及堆排序)
    js算法初窥01(排序算法01-冒泡、选择、插入)
    用js来实现那些数据结构16(图02-图的遍历)
    用js来实现那些数据结构15(图01)
  • 原文地址:https://www.cnblogs.com/fan-jiaming/p/10047017.html
Copyright © 2011-2022 走看看