zoukankan      html  css  js  c++  java
  • POJ 3273 Monthly Expense二分查找[最小化最大值问题]

    POJ 3273 Monthly Expense二分查找(最大值最小化问题)

    题目:Monthly Expense

    Description

    Farmer John is an astounding accounting wizard and has realized he might run out of money to run the farm. He has already calculated and recorded the exact amount of money (1 ≤ moneyi ≤ 10,000) that he will need to spend each day over the next N (1 ≤ N ≤ 100,000) days.

    FJ wants to create a budget for a sequential set of exactly M (1 ≤ MN) fiscal periods called "fajomonths". Each of these fajomonths contains a set of 1 or more consecutive days. Every day is contained in exactly one fajomonth.

    FJ's goal is to arrange the fajomonths so as to minimize the expenses of the fajomonth with the highest spending and thus determine his monthly spending limit.

    Input

    Line 1: Two space-separated integers: N and M
    Lines 2..N+1: Line i+1 contains the number of dollars Farmer John spends on the ith day

    Output

    Line 1: The smallest possible monthly limit Farmer John can afford to live with.

    Sample Input

    7 5
    100
    400
    300
    100
    500
    101
    400

    Sample Output

    500

    Hint

    If Farmer John schedules the months so that the first two days are a month, the third and fourth are a month, and the last three are their own months, he spends at most $500 in any month. Any other method of scheduling gives a larger minimum monthly limit.

    思路:

    1.先找出要二分的上下限,上限为所有天数花费的总和,下限为其中的最大话费,所要查找的最优解就在上限和下限之间

    2.在上限下限之间进行二分,若得到的堆数大于题目所给的堆数,则应将mid+1赋值为下限,否则应将mid赋值为上限。

    3.二分时得到堆数的判断,当总和大于mid时,堆数进行加一,而将总和重新进行赋值,否则总和一直相加,直到大于mid。

    4.得到的下限或者上限即为最优解。

    #include<stdio.h>
    #include<iostream>
    using namespace std;
    int ans[100005]; 
    int main()
    {
        int N,M;
        scanf("%d%d",&N,&M);
    	int sum=0,MAX=0;
        for(int i=0;i<N;i++)
        {
        	scanf("%d",&ans[i]);
        	sum+=ans[i];
        	MAX=max(MAX,ans[i]);
    	}
    	while(MAX<sum)
    	{
    		int mid=(MAX+sum)/2;
    		int s=0,cnt=0;
    		for(int i=0;i<N;i++)
    		{
    			s+=ans[i];
    			if(s>mid)//此时的最优解为mid,因为MAX!=sum 
    			//if(s>MAX)
    			{
    				cnt+=1;s=ans[i];
    			}
    		}
    		if(cnt<M) sum=mid;
    		else MAX=mid+1;
    	}
    	//跳出循环后 则MAX==sum 
    	printf("%d
    ",sum);
        return 0;
    }
  • 相关阅读:
    java中JVM的原理重温【转】
    JavaBean 规范
    Java编程规范[转]
    spring mvc 多数据源切换,不支持事务控制[一]
    03-连连看-连通分析
    02-连连看-用例分析
    01参考资料
    03-稀疏矩阵
    02-对不重复的一组数据查找
    01-用链式结构打印学生成绩单
  • 原文地址:https://www.cnblogs.com/yyaoling/p/12260447.html
Copyright © 2011-2022 走看看