zoukankan      html  css  js  c++  java
  • acwing 算法基础-贪心

    耍杂技的牛

    农民约翰的N头奶牛(编号为1…N)计划逃跑并加入马戏团,为此它们决定练习表演杂技。

    奶牛们不是非常有创意,只提出了一个杂技表演:

    叠罗汉,表演时,奶牛们站在彼此的身上,形成一个高高的垂直堆叠。

    奶牛们正在试图找到自己在这个堆叠中应该所处的位置顺序。

    这N头奶牛中的每一头都有着自己的重量Wi以及自己的强壮程度Si。

    一头牛支撑不住的可能性取决于它头上所有牛的总重量(不包括它自己)减去它的身体强壮程度的值,现在称该数值为风险值,风险值越大,这只牛撑不住的可能性越高。

    您的任务是确定奶牛的排序,使得所有奶牛的风险值中的最大值尽可能的小。

    输入格式
    第一行输入整数N,表示奶牛数量。

    接下来N行,每行输入两个整数,表示牛的重量和强壮程度,第i行表示第i头牛的重量Wi以及它的强壮程度Si。

    输出格式
    输出一个整数,表示最大风险值的最小可能值。

    数据范围
    1≤N≤50000,
    1≤Wi≤10,000,
    1≤Si≤1,000,000,000
    输入样例:
    3
    10 3
    2 5
    3 3
    输出样例:
    2
    代码:

    import java.util.Arrays;
    import java.util.Map;
    import java.util.Scanner;
    
    public class Main{
        public static void main(String[] args){
            Scanner sc = new Scanner(System.in);
            int n = sc.nextInt();
            Node[] nodes = new Node[n+5];
            for(int i=0;i<n;i++){
                int w = sc.nextInt();
                int s = sc.nextInt();
                nodes[i] = new Node(w,s);
            }
            Arrays.sort(nodes,0,n);
            int sum = 0;
            int res = Integer.MIN_VALUE;
            for(int i=0;i<n;i++){
                res = Math.max(res,sum-nodes[i].s);
                sum += nodes[i].w;
            }
            System.out.println(res);
        }
    }
    class Node implements Comparable<Node>{
        int w,s,sum;
    
        public Node(int w, int s) {
            this.w = w;
            this.s = s;
            this.sum = w+s;
        }
    
        @Override
        public int compareTo(Node o) {
            return this.sum-o.sum;
        }
    }
    

    区间选点

    给定N个闭区间[ai,bi],请你在数轴上选择尽量少的点,使得每个区间内至少包含一个选出的点。

    输出选择的点的最小数量。

    位于区间端点上的点也算作区间内。

    输入格式
    第一行包含整数N,表示区间数。

    接下来N行,每行包含两个整数ai,bi,表示一个区间的两个端点。

    输出格式
    输出一个整数,表示所需的点的最小数量。

    数据范围
    1≤N≤105,
    −109≤ai≤bi≤109
    输入样例
    3
    -1 1
    2 4
    3 5
    输出样例
    2

    思路:
    按照区间左端点排序,每次判断当前区间是否包含在上次选择的dis以内。
    如果不在,那么必然要在此区间中选择一个点,我们将dis赋值为当前区间的右端点。
    如果在,为了确保每个区间都被选择过一个点。我们需要令dis = min(dis,nodes[i].r);这样可以确保所有的区间都被选择过一个点。
    代码

    import java.util.Arrays;
    import java.util.Scanner;
    
    public class Main{
        static int n;
        public static void main(String[] args){
            Scanner sc = new Scanner(System.in);
            n = sc.nextInt();
            Node[] nodes = new Node[n+5];
            for(int i=0;i<n;i++){
                int a = sc.nextInt();
                int b = sc.nextInt();
                nodes[i] = new Node(a,b);
            }
            Arrays.sort(nodes,0,n);
            int res = 0;
            int dis = Integer.MIN_VALUE;
            for(int i=0;i<n;i++){
                if(nodes[i].l>dis) {
                    res++;
                    dis = nodes[i].r;
                }else{
                    dis = Math.min(dis,nodes[i].r);
                }
            }
            System.out.println(res);
        }
    }
    class Node implements Comparable<Node>{
        int l,r;
    
        public Node(int l, int r) {
            this.l = l;
            this.r = r;
        }
    
        @Override
        public int compareTo(Node o) {//按照左端点排序
            return this.l-o.l;
        }
    }
    

    最大不相交区间数量

    给定N个闭区间[ai,bi],请你在数轴上选择若干区间,使得选中的区间之间互不相交(包括端点)。

    输出可选取区间的最大数量。

    输入格式
    第一行包含整数N,表示区间数。

    接下来N行,每行包含两个整数ai,bi,表示一个区间的两个端点。

    输出格式
    输出一个整数,表示可选取区间的最大数量。

    数据范围
    1≤N≤105,
    −109≤ai≤bi≤109
    输入样例
    3
    -1 1
    2 4
    3 5
    输出样例:
    2
    思路
    在n个区间中选择若干个互不相交的区间,我们可以将区间按照右端点排序,每次判断当前区间是否和dis有交点,没有交点时,我们选择当前区间。
    代码

    import java.util.Arrays;
    import java.util.Scanner;
    
    public class Main{
        public static void main(String[] args){
            Scanner sc = new Scanner(System.in);
            int n = sc.nextInt();
            Node[] nodes = new Node[n+5];
            for(int i=0;i<n;i++){
                int a = sc.nextInt();
                int b = sc.nextInt();
                nodes[i] = new Node(a,b);
            }
            Arrays.sort(nodes,0,n);
            int res = 0;
            int dis = Integer.MIN_VALUE;
            for(int i=0;i<n;i++){
                if(dis<nodes[i].l){
                    res ++;
                    dis = nodes[i].r;
                }
            }
            System.out.println(res);
        }
    }
    class Node implements Comparable<Node>{
        int l,r;
    
        public Node(int l, int r) {
            this.l = l;
            this.r = r;
        }
    
        @Override
        public int compareTo(Node o) {
            return this.r-o.r;
        }
    }
    

    区间分组

    给定N个闭区间[ai,bi],请你将这些区间分成若干组,使得每组内部的区间两两之间(包括端点)没有交集,并使得组数尽可能小。
    输出最小组数。

    输入格式
    第一行包含整数N,表示区间数。

    接下来N行,每行包含两个整数ai,bi,表示一个区间的两个端点。

    输出格式
    输出一个整数,表示最小组数。

    数据范围
    1≤N≤105,
    −109≤ai≤bi≤109
    输入样例
    3
    -1 1
    2 4
    3 5
    输出样例:
    2
    思路:

    代码

    import java.util.Arrays;
    import java.util.Comparator;
    import java.util.PriorityQueue;
    import java.util.Scanner;
    
    public class Main{
        public static void main(String[] args){
            Scanner sc = new Scanner(System.in);
            int n = sc.nextInt();
            Node[] nodes = new Node[n+5];
            for(int i=0;i<n;i++){
                int a = sc.nextInt();
                int b = sc.nextInt();
                nodes[i] = new Node(a,b);
            }
            Arrays.sort(nodes,0,n,new Ok());
            PriorityQueue<Node> queue = new PriorityQueue<>();
            for(int i=0;i<n;i++){
                if(queue.size()==0||queue.peek().r>=nodes[i].l){
                    queue.add(nodes[i]);
                }else{
                    queue.poll();
                    queue.add(nodes[i]);
                }
            }
            System.out.println(queue.size());
        }
    }
    class Ok implements Comparator<Node> {
    
        @Override
        public int compare(Node o1, Node o2) {
            return o1.l-o2.l;
        }
    }
    class Node implements Comparable<Node>{
        int l,r;
    
        public Node(int l, int r) {
            this.l = l;
            this.r = r;
        }
    
        @Override
        public int compareTo(Node o) { //按照右端点排序
            return this.r-o.r;
        }
    }
    

    区间覆盖

    给定N个闭区间[ai,bi]以及一个线段区间[s,t],请你选择尽量少的区间,将指定线段区间完全覆盖。

    输出最少区间数,如果无法完全覆盖则输出-1。

    输入格式
    第一行包含两个整数s和t,表示给定线段区间的两个端点。

    第二行包含整数N,表示给定区间数。

    接下来N行,每行包含两个整数ai,bi,表示一个区间的两个端点。

    输出格式
    输出一个整数,表示所需最少区间数。

    如果无解,则输出-1。

    数据范围
    1≤N≤105,
    −109≤ai≤bi≤109,
    −109≤s≤t≤109
    输入样例
    1 5
    3
    -1 3
    2 4
    3 5
    输出样例:
    2

    代码:

    import java.util.Arrays;
    import java.util.Map;
    import java.util.Scanner;
    
    public class Main{
        public static void main(String[] args){
            Scanner sc = new Scanner(System.in);
            int s = sc.nextInt();
            int t = sc.nextInt();
            int n = sc.nextInt();
            Node[] nodes = new Node[n+5];
            for(int i=0;i<n;i++){
                int a = sc.nextInt();
                int b = sc.nextInt();
                nodes[i] = new Node(a,b);
            }
            Arrays.sort(nodes,0,n);
            int dis = s;
            int res = 0;
            for(int i=0;i<n;i++){
                if(nodes[i].l>dis){
                    System.out.println("-1");
                    return;
                }else{
                    res ++;
                    int temp = dis;
                    while(i<n&&nodes[i].l<=dis){
                        temp = Math.max(temp,nodes[i].r);
                        i++;
                    }
                    dis = temp;
                    i--;
                }
                if(dis>=t) break;
            }
            if(dis<t) System.out.println("-1");
            else System.out.println(res);
        }
    }
    class Node implements Comparable<Node>{
        int l,r;
        public Node(int l, int r) {
            this.l = l;
            this.r = r;
        }
        @Override
        public int compareTo(Node o) {
            return this.l-o.l;
        }
    }
    
  • 相关阅读:
    tomcat使用入门
    IDEA2020 创建springboot项目提示程序包org.springframework.boot不存在 问题
    jvm内存泄露
    tomcat 上设置可以直接访问的图片路径
    服务器上安装mysql后开启远程连接
    图的遍历,BFS和DFS的Java实现
    并查集
    深度优先搜索实现拓扑排序(leetcode210课程表)
    在Java中怎么实现字符'a'转成字符'b'
    MyBatis底层原理
  • 原文地址:https://www.cnblogs.com/fxzemmm/p/14847916.html
Copyright © 2011-2022 走看看