zoukankan      html  css  js  c++  java
  • 【NOIP模拟赛】工资

    工资

    【试题描述】

        聪哥在暑假参加了打零工的活动,这个活动分为n个工作日,每个工作日的工资为Vi。有m个结算工钱的时间,聪哥可以自由安排这些时间,也就是说什么时候拿钱,老板说的不算,聪哥才有发言权!(因为聪哥是土豪,他是老板的老板)

    聪哥不喜欢身上一次性有太多的钱,于是他想安排一下拿钱的时间,使他一次性拿的钱中最大的最小。(最后一天一定要领钱)

    【输入要求】

    最小的最大钱数。 

    【输出要求】

    最小的最大钱数。 

    【输入实例】

    7 5
    100
    400
    300
    100
    500
    101
    400
    

      

    【输出实例】

    500
    

    【其他说明】

    数据范围:
    20%   1<=n<=20
    另 20%  1<=n<=50,Vi的和不超过1000
    100%  1<=n<=100,000,m<=n,Vi<=10,000

    【试题分析】

         非常明显的二分题,这题貌似是我AK那天yy的第二题,第一眼没头绪,再想一想就简单多了,先把二分写出来,想明白right的值和left的值,要想明白,这里不是按个数二分的,而是按钱数二分的,由于right和left没想好,所以调了30多分钟程序QAQ,具体过程我们还是来直接看代码吧!

    【代码】

    #include<iostream>
    using namespace std;
    inline long long read(){
        int x=0,f=1;char c=getchar();
        for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
        for(;isdigit(c);c=getchar()) x=x*10+c-'0';
        return x*f;
    }
    int n,m;
    long long v[101000];
    long long l=-9999999,r;//为了后面要做好准备,不然……
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=0;i<n;i++)
        {
            v[i]=read();
            if(l<v[i]) l=v[i];//一开始l写对了,r写成v最大的数字了QAQ
            r+=v[i];
        }
        while(l<r)
        {
            long long mid=(l+r)/2;
            long long sum=0;
            long long time=1;
            for(int i=0;i<n;i++)
            {
                sum+=v[i];//sum+v[i]记录这一块的工资值
                if(sum>mid)
                {
                    time++;
                    sum=v[i];//重新开始
                }
             }
             if(time<=m) r=mid;//二分
             else l=mid+1;
        }
        printf("%lld",l);//由于l和r的值一样,所以可以输出任何一个
    }
    
  • 相关阅读:
    kmp
    RMP
    p次方求和
    河南省之6 Metric Matrice
    表达式求值
    线段树
    办公软件试题
    河南省之6 遥控器
    三个水杯
    JLink + USBTO232 MINI作品
  • 原文地址:https://www.cnblogs.com/wxjor/p/5791114.html
Copyright © 2011-2022 走看看