poj3273 Monthly Expenses

                                          Monthly Expense

Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 32155   Accepted: 12113

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

题意概括:给出n份钱数,把这n份钱分成m份,要求分成m份后,最大的那一份总和最小。求最大值最小的分法中最大值的值为多少。

解题思路:这个最大值一定是在n份钱中最大的那一份与所有n份钱的总和之间的一个数。因此在n份钱最大的那一份与n份钱的总和之间进行二分运算。对n份钱进行累加,如果累加结果超过mid,就新开一组。累加结束后,对比所开的组数group与m的大小对比,如果group大于m,说明组开多了,mid偏小;反之,说明组开少了,mid偏大。然后通过二分的方式,逐渐找到最优的mid,即为最大值最小的分法中最大值的值。

AC代码:

#include<stdio.h>

int n, m;

int search(int mid, int a[])
{
	int i, sum = 0, group = 1;   //第二次错误处,group从0开始的累加
        for(i = 1; i <= n; i ++)
	{
		if(sum + a[i] <= mid)  
		{
			sum += a[i];
		}
		else
		{
			sum = a[i];
			group ++; 
		}
	}
	if(group > m)
	{
		return 1;
	}
	else
	{
		return 0;
	}
}


int main(void)
{
	int i, high = 0, low = -99, mid, a[100005];   //第一次错误处,将a[100005]定义成了全局变量。
	scanf("%d%d", &n, &m);
	for(i = 1; i <= n; i ++)
	{
		scanf("%d", &a[i]);
		high += a[i];
		if(a[i] > low)
		{
			low = a[i];
		}
	}
	mid = (low + high) / 2;   //第三次错误处,漏写了首次的二分mid。
	 
	while(low < high)
	{
		if(search(mid, a) == 1)
		{
			low = mid + 1;
		}
		else
		{
			high = mid - 1;
		}
		mid = (low + high) / 2;
	}
	
	printf("%d\n", mid);
	return 0;
} 

错误原因:

1. 第一次错误处,将a[100005]定义成了全局变量。在有自定义函数且自定义函数中数组要从主函数传递给自定义函数的情况下,要将数组定义在主函数里面。

2. 第二次错误处,group从0开始的累加。应该从1开始累加。

3. 第三次错误处,漏写了首次的二分mid。导致首次二分时mid的值为空。

猜你喜欢

转载自blog.csdn.net/starlight321/article/details/79871526