zoukankan      html  css  js  c++  java
  • BZOJ1639: [Usaco2007 Mar]Monthly Expense 月度开支

    【传送门:BZOJ1639


    简要题意:

      约翰刷了N 次信用卡,第i次刷掉了Ai 元。银行告诉他可以在接下来的M个月里分期还清这 些债务,但是先发生的债务必须先偿还,也不能把一笔债务分在两个月里还。约翰想找到一种方法,使得每个月还的钱尽量均匀。请问,约翰应该在每个月还多少债务,才能使他在所有月份中的最大还款数额最小?


    输入格式:

      • 第一行:两个整数N 和M,1 ≤ M ≤ N ≤ 100000

      • 第二行到第N + 1 行:第i + 1 行有一个整数Ai,1 ≤ Ai ≤ 10000


    输出格式:

      • 单个整数:表示最大还款额的最小值


    样例输入:

    7 5

    100

    400

    300

    100

    500

    101

    400


    样例输出:

    500


    样例解释:

      前两笔放在第一个月,第三和第四笔放在第 二个月,最后三笔各自放在一个月


    题解:

      二分答案判断

      二分最大还款项的最小值,判断是否能够符合分成的月份小于等于m,并且得到的值小于二分的答案


    参考代码:

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cstdlib>
    #include<cmath>
    using namespace std;
    int a[110000];
    int s[110000];int n,m;
    bool check(int x)
    {
        int len=1,d=0;
        for(int i=1;i<=n;i++)
        {
            if(a[i]>x) return false;
            if(d+a[i]>x)
            {
                len++;d=a[i];
                if(len>m) return false;
            }
            else d+=a[i];
        }
        return true;
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++) scanf("%d",&a[i]);
        int l=0,r=1000000000;
        int ans=0;
        while(l<=r)
        {
            int mid=(l+r)/2;
            if(check(mid)==true)
            {
                ans=mid;
                r=mid-1;
            }
            else l=mid+1;
        }
        printf("%d
    ",ans);
        return 0;
    }
  • 相关阅读:
    TCP,IP,HTTP,SOCKET区别和联系
    添加Nginx为系统服务(设置开机启动)
    设计模式大全
    linux 命令行 光标移动技巧等
    Linux中ping命令
    TCP/IP协议 三次握手与四次挥手【转】
    Node 出现 uncaughtException 之后的优雅退出方案
    Google Protocol Buffers简介
    关于绝对路径和相对路径
    node定时任务——node-schedule模块使用说明
  • 原文地址:https://www.cnblogs.com/Never-mind/p/7761669.html
Copyright © 2011-2022 走看看