发邮件 装错信封
链接: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;
}
}