刷题日常day1

第一题: 最大报酬

在这里插入图片描述
使用动态规划解题

import java.util.Scanner;
public class nF {
        public static void main(String[] args) {
            Scanner scanner = new Scanner(System.in);
            int T = scanner.nextInt();
            int n = scanner.nextInt();
            int[] t = new int[n];
            int[] w = new int[n];
            for (int i = 0; i < n; i++) {
                t[i] = scanner.nextInt();
                w[i] = scanner.nextInt();
            }
            int[][] dp = new int[n + 1][T + 1];
            for (int i = 1; i <= n; i++) {
                for (int j = 1; j <= T; j++) {
                    if (t[i - 1] <= j) {
                        dp[i][j] = Math.max(dp[i - 1][j], dp[i - 1][j - t[i - 1]] + w[i - 1]);
                    } else {
                        dp[i][j] = dp[i - 1][j];
                    }
                }
            }
            System.out.println(dp[n][T]);
        }
}

第二题: 最大利润

在这里插入图片描述
在这里插入图片描述

import java.util.Scanner;
public class nD {
//        3
//        3
//        4 5 6
//        1 2 3
//        4 3 2
//        1 5 3
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);

        int item = scan.nextInt();
        int days = scan.nextInt();
        int[] maxNum = new int[item];
        int[][] arr = new int[item][days];
        for (int i = 0; i < item; i++) {
            maxNum[i] = scan.nextInt();
        }
        for (int i = 0; i < item; i++) {
            for (int j = 0; j < days; j++) {
                arr[i][j] = scan.nextInt();
            }
        }

        int profit = 0;
        for (int i = 0; i < item; i++) {
            profit += helper(arr[i], maxNum[i]);
            // System.out.println("current profit " + i + " is: " + profit);
        }

        System.out.print(profit);
    }

    public static int helper(int[] prices, int num) {
        int min = prices[0];
        int profit = 0;

        for (int i = 1; i < prices.length; i++) {
            if (prices[i] > min) {
                profit += (prices[i] - min) * num;
                min = prices[i];
            } else {
                min = prices[i];
            }
        }
        return profit;
    }

}

第三题: 匿名信

题目描述

电视剧《分界线》里面有一个片段,男主为了向警察透露案件细节,且不暴露自己,于是将报刊上的字减下来,剪拼成匿名信。
现在又一名举报人,希望借鉴这种手段,使用英文报刊完成举报操作。
但为了增加文章的混淆度,只需满足每个单词中字母数量一致即可,不关注每个字母的顺序。解释:单词on允许通过单词no进行替代。
报纸代表newspaper,匿名信代表anonymousLetter,求报纸内容是否可以拼成匿名信。

输入

第一行输入newspaper内容,包括1-N个字符串,用空格分开

第二行输入anonymousLetter内容,包括1-N个字符串,用空格分开
.newspaper和anonymousLetter的字符串由小写英文字母组成,且每个字母只能使用一次
.newspaper内容中的每个字符串字母顺序可以任意调整,但必须保证字符串的完整性(每个字符串不能有多余字母) .1 < N < 100,
1 <= newspaper.length,anonymousLetter.length <= 10^4

输出

如果报纸可以拼成匿名信返回true,否则返回false

样例输入

ab cd ab

样例输出

true

public class test2 {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String[] rew = scanner.nextLine().split(" "); // newspaper去除空格
        String[] let = scanner.nextLine().split(" ");   // anonymousLetter
         int flg = 0;   //设置一个标识
        for (int i = 0; i < let.length; i++) {
            for (int j = 0; j < rew.length; j++) {
                String a =sortString(rew[j]);   //调用sortString 方法给字符串排序
                String b = sortString(let[i]);
                if (b.length() == a.length() && b.contains(a) )
                    flg ++;        // 只要匿名信中元素在newspaper出现过就 +1
            }
        }
        System.out.println(flg == let.length ? true : false);
    }
    public static String sortString(String s) {
        char[] charArray = s.toCharArray(); //传换成char数组类型
        Arrays.sort(charArray);
        return new String(charArray);
    }
}

第四题: 磁盘容量排序

题目描述

磁盘的容量单位常用的有M,G,T这三个等级,它们之间的换算关系为1T = 1024G,1G = 1024M,
现在给定n块磁盘的容量,请对它们按从小到大的顺序进行稳定排序,
例如给定5块盘的容量,1T,20M,3G,10G6T,3M12G9M排序后的结果为20M,3G,3M12G9M,1T,10G6T。
注意单位可以重复出现,上述3M12G9M表示的容量即为3M+12G+9M,和12M12G相等。 输入 输入第一行包含一个整数n(2 <= n
<= 100),表示磁盘的个数, 接下的n行,每行一个字符串(长度大于2,小于30),表示磁盘的容量,
由一个或多个格式为mv的子串组成,其中m表示容量大小,v表示容量单位, 例如20M,1T,30G,10G6T,3M12G9M。
磁盘容量m的范围为1到1024的正整数,容量单位v的范围只包含题目中提到的M,G,T三种,换算关系如题目描述。

输出
输出n行,表示n块磁盘容量排序后的结果。

样例输入 
3
1G
2G
1024M

样例输出

1G
1024M
2G
import java.util.Scanner;
public class nB {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int num = Integer.parseInt(scanner.nextLine());
        String[] list = new String[num];
        for (int i = 0; i < num; i++) {
            list[i] = scanner.nextLine();
        }
        // 冒泡排序
        for (int i = 0; i < list.length - 1; i++) {
            for (int j = 0; j < list.length - 1 - i; j++) {
                if (unitCovert(list[j]) > unitCovert(list[j + 1])) {
                    String tem = list[j];
                    list[j] = list[j + 1];
                    list[j + 1] = tem;
                }
            }
        }
        for (String s : list) {
            System.out.println(s);
        }
    }

    // 单位换算
    private static int unitCovert(String string) {
        if (string.length() < 1) {
            return 0;
        }
        int end = string.length() - 1;
        int value = Integer.parseInt(string.substring(0, end));
        if (string.endsWith("T")) {
            return value * 1000000;
        } else if (string.endsWith("G")) {
            return value * 1000;
        } else {
            return value;
        }
    }
}


第五题: 高效的任务规划

题目描述

你有 n 台机器编号为 1~n,每台都需要完成完成一项工作,机器经过配置后都能完成独立完成一项工作。 假设第 i 台机器你需要花 B
分钟进行设置,然后开始运行,J 分钟后完成任务。 现在,你需要选择布置工作的顺序,使得用最短的时间完成所有工作。
注意,不能同时对两台进行配置,但配置完成的机器们可以同时执行他们各自的工作。 输入 第一行输入代表总共有 M 组任务数据(1<M<=10)。
每组数第一行为一个整数指定机器的数量 N(0<N<=1000)。 随后的 N 行每行两个整数,第一个表示
B(0<=B<=10000),第二个表示 J(0<=J<=10000)。 每组数据连续输入,不会用空行分隔。各组任务单独计时。

输出

对于每组任务,输出最短完成时间,且每组的结果独占一行。例如,两组任务就应该有两行输出。

样例输入

1
1
2 2

样例输出

4
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int numCases = scanner.nextInt(); // 总共有多少组任务

        for (int i = 0; i < numCases; i++) {
            int numMachines = scanner.nextInt(); // 机器的数量
            int totalTime = 0; // 总共所需时间

            for (int j = 0; j < numMachines; j++) {
                int setupTime = scanner.nextInt(); // 设置时间
                int jobTime = scanner.nextInt(); // 任务完成时间

                totalTime = Math.max(totalTime, setupTime + jobTime); // 取最长时间
            }

            System.out.println(totalTime);
        }

        scanner.close();
    }
}

第六题:最大平分数组

题目描述

给定一个数组nums,可以将元素分为若干个组,使得每组和相等,求出满足条件的所有分组中,最大的平分组个数。 输入 第一行输入 m

接着输入m个数,表示此数组

数据范围:1<=M<=50, 1<=nums[i]<=50
输出 最大的平分组数个数。

样例输入

7
4 3 2 3 5 2 1

样例输出

4
import java.util.ArrayList;
import java.util.Scanner;
 
class Main {
 
    //数组容器
    public static int[] nums;
    //数组选择记录
    public static boolean[] choose;
    //数组元素总和
    public static int sum;
    //搜索结果(sum是否可以被分为和为des的若干子数组)
    public static boolean falg = false;
    //满足条件的最小因数
    public static int minFactor;
 
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int size = Integer.parseInt(in.nextLine());
        nums = new int[size];
        choose = new boolean[size];
 
        //获取数组和sum
        String[] strings = in.nextLine().split(" ");
        for (int i = 0; i < strings.length; i++) {
            nums[i] = Integer.parseInt(strings[i]);
            sum += nums[i];
        }
 
        //获取sum的因数(不需要sum自身)
        ArrayList<Integer> factors = new ArrayList<>();
        for (int i = 1; i <= sum/2; i++) {
            if (sum % i == 0) {
                factors.add(i);
            }
        }
 
        //可优化:有大于des的元素可以直接判定false
 
        //遍历由小到大寻找符合条件的因数
        falg = false;
        for (int i = 0; i < factors.size(); i++) {
            dfs(0, factors.get(i), 0, 0);
            if (falg) {
                minFactor = factors.get(i);
                break;
            }
        }
        //如果没有找到符合的因数,那么答案就是sum本身(只分一组)
        if (minFactor == 0) {
            minFactor = sum;
        }
        System.out.println(minFactor);
    }
 
    /**
     * 遍历各种组合判断是否可以按目标和分组
     * 调用之前应先验证目标元素可行(先验证des是sum的一个因数)
     * 至少两等分再调用,1等分不要调用,直接出结果
     * @param index 当前索引
     * @param des 子数组目标元素和
     * @param countI 当前子数组组号
     * @param countD 当前子数组当前元素和
     */
    public static void dfs(int index,int des,int countI,int countD) {
        //当本组元素和没达到目标时
        if (index < choose.length && !choose[index] && countD < des) {
            //选取当前元素
            choose[index] = true;
            dfs(index + 1, des, countI, countD + nums[index]);
            //不选取当前元素
            choose[index] = false;
            dfs(index + 1, des, countI, countD);
        } else if (countD == des) {//当恰好达到目标时
            //当倒数第二组组合完成,倒数第一组不需验证,直接通过
            if (countI == sum / des - 2) {
                falg = true;
            } else if (countI < sum / des - 2) {
                int start = -1;
                for (int i = 0; i < choose.length; i++) {
                    if (!choose[i]) {
                        start = i;
                        break;
                    }
                }
                if (start == -1) {
                    return;
                }
                dfs(start, des, countI + 1, 0);
            }
        }
    }
 
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值