1. 程式人生 > >CodeForces - 363D --二分和貪心

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