【POJ 3273】 Monthly Expense (二分)

本文介绍了一个农民如何通过二分法找到最优的月支出方案,将连续的每日支出划分为M个月内完成,目标是最小化每月的最大支出。通过设定合理的上下界并逐步逼近最优解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

【POJ 3273】 Monthly Expense (二分)

一个农民有块地 他列了个计划表 每天要花多少钱管理 但他想用m个月来管理 就想把这个计划表分割成m个月来完成 想知道每个月最少花费多少 每个月的花费是这个月的花费加和 必须按计划表的顺序来

所有天中花费中最大花费作为下界 所有花费加和作为上界 二分上下界间的花费可能 找出最少每月花费即可


代码如下:

#include <iostream>
#include <cstdio>

using namespace std;

int ned[100000],n,m;

bool can(int x)//判断是否可行
{
    int i,sum = 0,cnt = 1;
    for(i = 0; i < n; ++i)
    {
        sum += ned[i];
        if(sum > x)//加上这天后此划分超过x 割开
        {
            sum = ned[i];
            cnt++;
        }
    }
    if(cnt > m) return false;//划分块数>m 不可行
    return true;
}

int main()
{
    //freopen("in.in","r",stdin);
    int l,r,i,mid,ans;
    scanf("%d %d",&n,&m);
    r = l = 0;
    for(i = 0; i < n; ++i)
    {
        scanf("%d",&ned[i]);
        r += ned[i];
        l = max(l,ned[i]);
    }

    while(l <= r)
    {
        mid = (l+r)>>1;
        if(can(mid)) //可按mid划分的时候 此题数据真水 开始二分写挫了 还过了 3 2 4 4 4这组就能卡掉
        {
            ans = mid;
            r = mid-1;
        }
        else l = mid+1;
    }
    printf("%d\n",ans);
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值