POJ 3273 Monthly Expense(二分枚举)

本文介绍了如何通过简单的二分枚举方法解决POJ平台上的问题编号为3273的挑战。文章详细阐述了解题思路,包括利用贪心算法在枚举过程中进行优化,使得算法复杂度达到O(n*logn),从而高效地找到满足题目条件的最小整数。通过实例分析,展示了这种算法在实际问题求解中的应用。

题目链接:http://poj.org/problem?id=3273


这个题目开始以为又是动态规划什么的,其实直接枚举就可以做了,复杂度也很低

这个题目直接二分枚举,找到满足题目条件的最小值,不过这里在枚举的时候要判断当前枚举的值

是否满足题目条件,这个用到一点点贪心算法不过很简单就是了,因为要连续的天数,所以就一直加

也就是前面的分组尽量在满足条件的情况下尽量大就OK了,贪心的判断每个枚举条件是否符合,每次判断

O(n)枚举logn

O(n*logn)的算法过这个题目还是比较轻松的!


/*3273*/
#include <iostream>
#include <string.h>
#include <stdio.h>
#include <algorithm>
using namespace std;
#define maxn 110000
int rec[maxn];
int n,m;
bool is_ok(int num,int limit)
{
    int i,p=0,ans=0;
    for(i=0;i<n;i++)
    {
        if(ans+rec[i]<=limit)
        ans+=rec[i];
        else
        {
            p++;
            if(p>=num)
            return false;
            ans=0;
            i--;
            if(i<0)
            i=0;
        }
    }
    if(ans>0)
    p++;
    if(p>num)
    return false;
    return true;
}
int find_ans(int l,int r,int day)
{
    int mid,ans=1000000000;
    while(l<=r)
    {
        mid=(l+r)>>1;
        if(is_ok(day,mid))
        {
            //printf("ans:%d %d\n",mid,ans);
            ans=(ans < mid ? ans : mid);
            r=mid-1;
        }
        else
        {
            l=mid+1;
        }
    }
    printf("%d\n",ans);
    return 0;
}
int main()
{
    int i,MAX,sum;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        MAX=0;
        sum=0;
        for(i=0;i<n;i++)
            scanf("%d",&rec[i]);
        find_ans(0,1000000000+1,m);
       // printf("OK%d\n",is_ok(m,500));
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值