首页 > 代码库 > SDUT 2778-小明的花费预算(二分答案)
SDUT 2778-小明的花费预算(二分答案)
小明的花费预算
Time Limit: 1000ms Memory limit: 65536K 有疑问?点这里^_^
题目描述
小明终于找到一份工作了,但是老板是个比较奇怪的人,他并不是按照每月每月的这样发工资,他觉得你想什么时候来取都可以,取的是前边连续几个月中没有取的工资,而小明恰好是一个花钱比较大手大脚的人,所以他希望每次取得钱正好够接下来的n个月的花费。
所以让你把这n个月分成正好m组。每个组至少包含一个月,每组之中的月份必须是连续的,请你为他分组,使得分得的组中最大的总花费最小。
输入
第一行是两个整数,n(1 ≤ n ≤ 100,000)和m (1 ≤ m ≤ n)
接下来的n行是连续n个月的花费,第i+1行是第i个月的花费。
输出
输出满足最大的总花费最小的那个组的总花费。
示例输入
5 3 3 2 9 4 1
示例输出
9
初次接触二分答案,简单的说,就是对一个问题的答案,我们可以大致确定一个范围,然后在这个范围中二分,为什么可以二分呢?其实是有要求的,答案要具有单调性。就是说对于mid,经过判断后,我们可以确定答案一定是在mid左还是mid右。二分答案常用于求极大值中的最小值,极小值中的最大值等。。
#include <algorithm> #include <iostream> #include <cstring> #include <cstdlib> #include <string> #include <cctype> #include <vector> #include <cstdio> #include <cmath> #include <deque> #include <stack> #include <map> #include <set> #define ll long long #define maxn 100010 #define pp pair<int,int> #define max(x,y) ( ((x) > (y)) ? (x) : (y) ) #define min(x,y) ( ((x) > (y)) ? (y) : (x) ) using namespace std; int n, m, a[maxn], high, low; bool jduge(int mid) { int cnt = 1, s = 0; for (int i = 0; i < n; i++) { if (s + a[i] <= mid) { s += a[i]; } else { cnt++; s = a[i]; } } if (cnt <= m) { return 1; } else { return 0; } } void solve() { int mid; while (low <= high) { mid = (low + high) / 2; if (jduge(mid)) { high = mid - 1; } else { low = mid + 1; } } printf("%d\n", mid); } int main() { while (~scanf("%d%d", &n, &m)) { high = 0; low = 0; for (int i = 0; i < n; i++) { scanf("%d", a + i); low = max(a[i], low); high += a[i]; } solve(); } return 0; }
SDUT 2778-小明的花费预算(二分答案)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。