蓝桥杯训练营第三周作业

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);
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值