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;
    }
  • 相关阅读:
    协变与逆变
    反射
    TreeCombo
    使用TreeCombo示例
    Calling R from java using JRI
    [转]相似度计算常用方法综述
    [转]聚类算法KMeans, KMedoids, GMM, Spectral clustering,Ncut
    Learning D3.js with App iLearning D3.js
    [repost ]经典的机器学习方面源代码库
    [转]数据挖掘中所需的概率论与数理统计知识、上
  • 原文地址:https://www.cnblogs.com/yyaoling/p/12260447.html
Copyright © 2011-2022 走看看