SDUT 2778 小明的花费预算
来源:互联网 发布:vue.js实战 pdf 编辑:程序博客网 时间:2024/04/30 12:42
SDUT 2778 小明的花费预算
Time Limit: 1000MS Memory Limit: 65536KB
Problem Description
小明终于找到一份工作了,但是老板是个比较奇怪的人,他并不是按照每月每月的这样发工资,他觉得你想什么时候来取都可以,而小明恰好是一个花钱比较大手大脚的人,所以他希望每次取得钱正好够接下来的n个月的花费,以防浪费。
小明很懒,懒到他连钱都尽量不愿多带(只是嫌沉)。但是他在只有m次取钱的机会,所以他想要用m次把n个月的钱都取出来,但想要每次都尽量少取些。给你小明n个月的花费,还有可取的次数m,问小明在保证每次尽量少取些钱的情况下,最多的那次取了多少钱?当然,每次取钱只能取连续几个月的花费。
Input
多组输入。
第一行是两个整数,n(1 ≤ n ≤ 100,000)和m (1 ≤ m ≤ n)
接下来的n行是连续n个月的花费,第i+1行是第i个月的花费。
Output
输出满足最大的总花费最小的那个组的总花费。
Example Input
5 3
3
2
9
4
1
Example Output
9
Hint
将5个月分为3组,第一组(3,2),第二组(9),第三组(4,1),第二组的总花费最大为9,若按其他的方式分,花费最大的那一组的总花费将>=9.
Author
lwn
Submit(带注释版)
#include <bits/stdc++.h>using namespace std;int N, M;int n[100005];int ans;void binsearch(int low, int high){ if(low > high)//从low到high,情况越来越不理想,所以必须low <= high,当low > high的时候说明最佳答案ans已求出 return; int mid, count = 1, i, sum = 0;//count代表取钱次数,sum代表每次取得钱数 mid = (high-low) / 2 + low;//二分,设一个low和high的中值mid,代表每次允许取的最大钱数 for(i = 0; i < N; i++)//求出若每次取得钱数不超过中值mid的条件下需要取几次 { if(sum + n[i] <= mid)//再继续取1月的花费不会超过mid sum += n[i];//sum代表某一次取的钱数 else { count++;//不能继续再取钱了,要再取一次 sum = n[i]; } } if(count > M)//需要取的次数大于允许取得次数,说明每次允许取的钱数太小了,就确定答案范围一定在mid到high之间 binsearch(mid+1, high); else { ans = mid; binsearch(low, mid-1);//反之就减小每次允许取得钱数 }}int main(){ int low, high;//low和high是总花费最小的那个组的总花费的范围 while(~scanf("%d %d", &N, &M)) { low = high = 0;//总花费最小的最理想情况就是,花费最大的那个月单独取1次,其他任意次取的钱数合都比这个月小,此处设low是这个最理想情况的花费。最不理想情况则是只取一次,一次取出所有的花费,此处设low是这个最不理想情况 for(int i = 0; i < N; i++) { scanf("%d", &n[i]); if(n[i] > low) low = n[i];//最理想情况 high += n[i];//最大花费就是只取一次全取完 } binsearch(low, high);//二分的在这个范围内精确答案 printf("%d\n", ans); } return 0;}
Submit(纯代码版)
#include <bits/stdc++.h>using namespace std;int N, M;int n[100005];int ans;void binsearch(int low, int high){ if(low > high) return; int mid, count = 1, i, sum = 0; mid = (high-low) / 2 + low; for(i = 0; i < N; i++) { if(sum + n[i] <= mid) sum += n[i]; else { count++; sum = n[i]; } } if(count > M) binsearch(mid+1, high); else { ans = mid; binsearch(low, mid-1); }}int main(){ int low, high; while(~scanf("%d %d", &N, &M)) { low = high = 0; for(int i = 0; i < N; i++) { scanf("%d", &n[i]); if(n[i] > low) low = n[i]; high += n[i]; } binsearch(low, high); printf("%d\n", ans); } return 0;}
阅读全文
0 0
- SDUT 2778 小明的花费预算
- SDUT 2778 小明的花费预算 二分
- [2778]小明的花费预算 (二分查找)SDUT
- SDUT 2778-小明的花费预算(二分答案)
- SDUT 小明的花费预算 2778(二分)
- SDUT 2778 小明的花费预算 (二分答案) -- 解题报告
- 小明的花费预算
- SDUT2778 小明的花费预算
- 二分答案:小明的花费预算
- 寒假训练--二分哈希--小明的花费预算
- sdut2778 小明的花费预算(二分)
- 小明的骰子 SDUT
- 小明的骰子(SDUT 2859)
- SDUT 2859 小明的骰子
- 小明的骰子 SDUT 2859
- 金明的预算
- 金明的预算方案
- 金明的预算方案
- Could not create the view: An unexpected exception was thrown.问题解决
- 树的创建及点击事件Java
- 霍夫曼编码
- Pentaho BI源码编译
- 数据结构实验之排序七:选课名单
- SDUT 2778 小明的花费预算
- UVA Live 3704 Cellular Automaton (循环矩阵+快速幂)
- 在Spark集群中,集群的节点个数、RDD分区个数、cpu内核个数三者与并行度的关系??
- Python 爬虫学习系列教程
- [bigdata-091] 规则引擎 easyrules 开发
- Message Flood
- 1028. 人口普查(20)
- 算法思想——单调队列(Foj志愿者问题)
- 合并区间