【★】【思特奇杯·云上蓝桥-算法集训营】第 3 周

杨辉三角形

题目描述:

题目描述

解题思路:

找规律
杨辉三角组合数 的关系,并根据 对称性 求解

代码如下:

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        int n = scan.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;
            }
        }
    }

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

    static long min(long a, long b) {
        return b == 0 ? a : min(b, a % b);
    }

节点选择

题目描述:

题目描述

解题思路:

DP

代码如下:

package Demo;
import java.io.*;
import java.util.*;

public class Main {
    private static int[][] dp;
    private static 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<Integer>());
        }
        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 (int i = 0; i < temp.size(); i++) {
            if (temp.get(i) != pre) {
                dfs(temp.get(i), root);
                dp[root][1] += dp[temp.get(i)][0];
                dp[root][0] += Math.max(dp[temp.get(i)][0], dp[temp.get(i)][1]);
            }
        }
    }
}

耐摔指数

题目描述:

题目描述

解题思路:

动态规划

代码如下:

public class Demo{
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.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 好数

题目描述:

题目描述

解题思路:

DP

代码如下:

class Demo {
    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);
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值