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的值为空。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值