CodeForces - 363D --二分和贪心

题目:CodeForces - 363D 

题意:给定n个学生,其中每个学生都有各自的私己钱,并且自己的私己钱只能用在自己买自行车,不能给别人。

   给定m个自行车,每个自行车都有一个价格。

   给定公有财产a。

     然后求出这些学生能买自行车的最大数量,并且求当买下最大自行车数量时,总体花费私己钱的最少的钱。

我先来说以下二分搜索模板:

//右值点不能取到的情况
    int binary_search(vector<int>& nums,int left,int right, int target) { 
    //坑点(1)right究竟能不能取到的问题,这里是不能取到的情况
        int i = left;
        int j= right;
        while(i<j){
            int mid = i+(j-i)/2;             //坑点(2)这里尽量这么写,因为如果写成(i+j)/2则有溢出的风险
            if(nums[mid]>=target)        //坑点(3)这个地方大于还是大于等于要依据情况而定
                j = mid;            //坑点(4)因为右值点反正不能取到,所以j就可以等于mid
            else
                i = mid+1;           //坑点(5)
        }
        return i;
    }

//右值点能取到的情况
    int searchInsert(vector<int>& nums,int left,int right, int target) {
        int i = left;
        int j= right;
        while(i<=j ){
            int mid = i+(j-i)/2;
            if(nums[mid]>=target)
                j = mid-1;
            else
                i = mid+1;
        }
        return i;
    }

原文:https://blog.csdn.net/haolexiao/article/details/53541837 
版权声明:本文为博主原创文章,转载请附上博文链接!

明显是用二分和贪心的方法来实现的,我的代码实现如下:

。。。。。。(我做了好长时间,才做出来的,是用了二分模板一,就是右边点不能取得情况)

代码实现如下:

import java.util.Arrays;
import java.util.Scanner;

public class Main
{
    static final int MAX = 100005;
    static int N[] = new int[MAX];
    static int M[] = new int[MAX];
    static int n,m,a;
    public static void main(String []args)
    {
        Scanner cin = new Scanner(System.in);
        n = cin.nextInt();
        m = cin.nextInt();
        a = cin.nextInt();
        for(int i = 0; i < n; i++)
        {
            N[i] = cin.nextInt();
        }
        for(int i = 0; i < m; i++)
        {
            M[i] = cin.nextInt();
        }
        Arrays.sort(N, 0,n);
        Arrays.sort(M, 0,m);
        //第一步,先找出能最多租的自行车数量,用变量real保存
        int real = 0;
        int left = 0;
        int right = Math.min(n, m)+1;//这个1不能省,省了就错了,我就是被坑在这里一天。。。。。。
        while(left < right)
        {
            int mid = left+(right-left)/2;
            //检查当车辆为mid时,能否买得起。
            if(check(mid))
            {
                real = mid;
                left = mid+1;
            }
            else
            {
                right = mid;
            }
            //System.out.println(real);
        }
        if(real == 0)
        {
            System.out.println(0 + " " + 0);
            return;
        }
        System.out.print(real + " ");
        long sum = 0;
        for(int i = 0; i < real; i++)
        {
            sum += M[i];
        }
        if(sum <= a)
        {
            System.out.print(0);
        }
        else
        {
            System.out.print((sum-a));
        }
    }
    static boolean check(int K)
    {
        //最多钱的K个学生买最低价的K辆自行车
        long sum = 0;
        for(int i = 0; i < K; i++)
        {
            long result = M[i]-N[n-K+i];
            if(result > 0)
            {
                sum += result;
            }
        }
        if(sum <= a)
        {
            return true;
        }
        return false;
    }
}

猜你喜欢

转载自www.cnblogs.com/674001396long/p/10022534.html