牛客 发邮件(类似于装信封)经典的错排问题最长上升子序列

发邮件 装错信封

链接:https://www.nowcoder.com/questionTerminal/95e35e7f6ad34821bc2958e37c08918b
NowCoder每天要给很多人发邮件。有一天他发现发错了邮件,把发给A的邮件发给了B,把发给B的邮件发给了A。于是他就思考,要给n个人发邮件,在每个人仅收到1封邮件的情况下,有多少种情况是所有人都收到了错误的邮件?
即没有人收到属于自己的邮件。
思路(装信封)
用A、B、C……表示写着n位友人名字的信封,a、b、c……表示n份相应的写好的信纸。
把错装的总数为记作Der(n)。假设把a错装进B里了,包含着这个错误的一切错装法分两类:
b装入A里,这时每种错装的其余部分都与A、B、a、b无关,应有Der(n-2)种错装法。
b装入A、B之外的一个信封,这时的装信工作实际是把(除a之外的)n-1份信纸b、c……装入(除B以外的)n-1个信封A、C……,显然这时装错的方法有Der(n-1)种。
总之在a装入B的错误之下,共有错装法Der(n-2)+Der(n-1)种。
a装入C,装入Der……的n-2种错误之下,同样都有Der(n-1)+Der(n-2)种错装法,因此
Der(n)=(n-1)*[Der(n-1)+Der(n-2)]
代码

public class Main{
    public static void main(String[]args){
        Scanner sc=new Scanner(System.in);
        while(sc.hasNext()){
        int num=sc.nextInt();
        long sum=test(num);
        System.out.println(sum);
    }
    }
    public static long test(int n){

  if (n == 1) {
            return 0;
        } else if (n == 2) {
            return 1;
        } else {
            return (n - 1) * (test(n - 1) + test(n - 2));
        }
    }
}

最长上升子序列

链接https://www.nowcoder.com/questionTerminal/d83721575bd4418eae76c916483493de
题目
在这里插入图片描述
思路
在这里插入图片描述
代码

public class Main{
    public static void main(String[]args){
        Scanner sc=new Scanner(System.in);
        while(sc.hasNext()){
            int num=sc.nextInt();
            int[] height = new int[num];
            for(int i = 0; i < num; i++){
                height[i] = sc.nextInt();
            }
            System.out.println(longest(height,num));
        }
    }

  public static int longest(int[] height, int n){
        if(height == null || n <= 0 || height.length != n)
            return 0;
        int[] dp = new int[n];
     for(int i=0;i<n;i++){
         dp[i]=1;
     }
        int max = 1;
      
        for(int i = 0; i < n; i++){
            for(int j = 0; j <i; j++){
                if(height[i] > height[j])
                    dp[i] = Math.max(dp[i], dp[j] + 1);
            }
          max=Math.max(max,dp[i]);
        }
 
        return max;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值