19201419曾宇杰
斐波那契数
斐波那契数,通常用 F(n) 表示,形成的序列称为 斐波那契数列 。该数列由 0 和 1 开始,后面的每一项数字都是前面两项数字的和。也就是:
F(0) = 0,F(1) = 1
F(n) = F(n - 1) + F(n - 2),其中 n > 1
给你 n ,请计算 F(n) 。
import java.util.Scanner;
public class Q1 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
System.out.println(fib(n));
}
public static int fib(int n) {
return n <= 1 ? n : fib(n - 1) + fib(n - 2);
}
}
第 N 个泰波那契数
泰波那契序列 Tn 定义如下:
T0 = 0, T1 = 1, T2 = 1, 且在 n >= 0 的条件下 Tn+3 = Tn + Tn+1 + Tn+2
给你整数 n,请返回第 n 个泰波那契数 Tn 的值。
import java.util.Scanner;
public class Q2 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
System.out.println(tribonacci(n));
}
public static int tribonacci(int n) {
if (n == 0) {
return 0;
}
if (n <= 2) {
return 1;
}
int p = 0, q = 0, r = 1, s = 1;
for (int i = 3; i <= n; ++i) {
p = q;
q = r;
r = s;
s = p + q + r;
}
return s;
}
}
爬楼梯
假设你正在爬楼梯。需要 n
阶你才能到达楼顶。
每次你可以爬 1
或 2
个台阶。你有多少种不同的方法可以爬到楼顶呢?
public class Q3 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
System.out.println(climbStairs(n));
}
public static int climbStairs(int n) {
int p = 0, q = 0, r = 1;
for (int i = 1; i <= n; ++i) {
p = q;
q = r;
r = p + q;
}
return r;
}
}
使⽤最⼩花费爬楼梯
给你一个整数数组 cost ,其中 cost[i] 是从楼梯第 i 个台阶向上爬需要支付的费用。一旦你支付此费用,即可选择向上爬一个或者两个台阶。
你可以选择从下标为 0 或下标为 1 的台阶开始爬楼梯。
请你计算并返回达到楼梯顶部的最低花费。
public class Q4 {
public static void main(String[] args) {
int[] arr = {10, 15, 20};
System.out.println(minCost(arr));
}
public static int minCost(int[] cost) {
int n = cost.length;
int[] dp = new int[n + 1];
dp[0] = dp[1] = 0;
for (int i = 2; i <= n; i++) {
dp[i] = Math.min(dp[i - 1] + cost[i - 1], dp[i - 2] + cost[i - 2]);
}
return dp[n];
}
}
买卖股票的最佳时机
给定一个数组 prices ,它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。
你只能选择 某一天 买入这只股票,并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。
返回你可以从这笔交易中获取的最大利润。如果你不能获取任何利润,返回 0 。
public class Q5 {
public static void main(String[] args) {
int[] arr = {7, 1, 5, 3, 6, 4};
System.out.println(maxProfit(arr));
}
public static int maxProfit(int[] prices) {
int maxprofit = 0;
for (int i = 0; i < prices.length - 1; i++) {
for (int j = i + 1; j < prices.length; j++) {
int profit = prices[j] - prices[i];
if (profit > maxprofit) {
maxprofit = profit;
}
}
}
return maxprofit;
}
}
最长公共子序列
给定两个字符串 text1 和 text2,返回这两个字符串的最长 公共子序列 的长度。如果不存在 公共子序列 ,返回 0 。
一个字符串的 子序列 是指这样一个新的字符串:它是由原字符串在不改变字符的相对顺序的情况下删除某些字符(也可以不删除任何字符)后组成的新字符串。
例如,"ace" 是 "abcde" 的子序列,但 "aec" 不是 "abcde" 的子序列。
两个字符串的 公共子序列 是这两个字符串所共同拥有的子序列。
public class Q6 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String str1 = sc.nextLine();
String str2 = sc.nextLine();
System.out.println(longest(str1, str2));
}
public static int longest(String text1, String text2) {
int m = text1.length(), n = text2.length();
int[][] dp = new int[2][n + 1];
for (int i = 1; i <= m; i++) {
int r = i % 2;
char c1 = text1.charAt(i - 1);
for (int j = 1; j <= n; j++) {
char c2 = text2.charAt(j - 1);
if (c1 == c2) {
dp[r][j] = dp[1 - r][j - 1] + 1;
} else {
dp[r][j] = Math.max(dp[1 - r][j], dp[r][j - 1]);
}
}
}
return dp[m % 2][n];
}
}
杨辉三角
import java.util.Scanner;
public class Q7 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
for(int k = 16; k >= 0; k--){
int left = 2 * k;
int right = Math.max(n, left);
int r = -1;
while(left <= right){
int mid = (left + right) >> 1;
if(C(mid, k, n) >= n){
right = mid - 1;
r = mid;
}else{
left = mid + 1;
}
}
if(C(r, k, n) == n){
System.out.println((long)(r +1) * r/2 + k + 1);
break;
}
}
}
public static long C(long n , long k, long target){
long right = 1, left = 1;
if(k > n / 2){
k = n - k;
}
for (int i = 1; i <= k; i++) {
right *= n - i + 1;
left *= i;
long g = min(right, left);
right /= g;
left /= g;
if(right / left > target){
return right /left;
}
}
return right / left;
}
public static long min(long a, long b) {
return b == 0 ? a : min(b, a % b);
}
}
节点选择
import java.io.*;
import java.util.*;
public class Q8 {
static int[][] dp;
static final List<List<Integer>> vertex = new ArrayList<>();
public static void main(String[] args)throws IOException {
Scanner scanner = new Scanner(System.in);
int n=scanner.nextInt();
dp = new int[n][2];
for (int i = 0; i < n; i++) {
dp[i][1]=scanner.nextInt();
vertex.add(new ArrayList<>());
}
scanner.nextLine();
for (int i = 0; i < n - 1; i++) {
final String[] ab =scanner.nextLine().split(" ");
int a = Integer.parseInt(ab[0]) - 1;
int b = Integer.parseInt(ab[1]) - 1;
vertex.get(a).add(b);
vertex.get(b).add(a);
}
scanner.close();
dfs(0, -1);
System.out.println(Math.max(dp[0][0], dp[0][1]));
}
private static void dfs(int root, int pre) {
List<Integer> temp = vertex.get(root);
for (Integer integer : temp) {
if (integer != pre) {
dfs(integer, root);
dp[root][1] += dp[integer][0];
dp[root][0] += Math.max(dp[integer][0], dp[integer][1]);
}
}
}
}
耐摔指数
import java.util.Scanner;
public class Q9 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int[][] dp = new int[4][n+1];
for(int i=1;i<=n;i++){
dp[1][i] = i;
}
for(int i=1;i<=n;i++){
int val = Integer.MAX_VALUE;
for(int j=1;j<=i;j++){
int temp = 1 + Math.max(dp[2][i-j],dp[1][j-1]);
val = Math.min(val,temp);
}
dp[2][i] = val;
}
for(int i=1;i<=n;i++){
int val = Integer.MAX_VALUE;
for(int j=1;j<=i;j++){
int temp = 1 + Math.max(dp[3][i-j],dp[2][j-1]);
val = Math.min(val,temp);
}
dp[3][i] = val;
}
System.out.println(dp[3][n]);
}
}
K好数
import java.util.Scanner;
public class Q10 {
final static int Mod=1000000007;
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int K=sc.nextInt();
int L=sc.nextInt();
int sum=0;
int[][] arr=new int[L+1][K];
for(int i=1;i<=L;i++){
for(int j=0;j<K;j++) {
arr[i][j]=0;
}
}
for(int i=0;i<K;i++){
arr[1][i]=1;
}
for(int i=2;i<=L;i++){
for(int j=0;j<K;j++){
for(int x=0;x<K;x++){
if(x!=j-1 && x!=j+1){
arr[i][j] += arr[i-1][x];
arr[i][j] %=Mod;
}
}
}
}
for(int j=1;j<K;j++){
sum +=arr[L][j];
sum%=Mod;
}
System.out.println(sum);
}
}