POJ 3273 Monthly Expense(二分)
2016-03-15 00:53
381 查看
题目链接:点击打开链接
题目大意是说给n个数,要求分成m组,必须连续的数才能合并成一个组,求满足ans大于等于每一组的和的最小ans(每个组可以只有1个数)
显然二分查找最小的ans
题目大意是说给n个数,要求分成m组,必须连续的数才能合并成一个组,求满足ans大于等于每一组的和的最小ans(每个组可以只有1个数)
显然二分查找最小的ans
//Must so #include<iostream> #include<algorithm> #include<string> #include<sstream> #include<queue> #include<vector> #include<set> #include<map> #include<cstring> #include<cstdio> #include<cmath> #define mem(a,x) memset(a,x,sizeof(a)) #define sqrt(n) sqrt((double)n) #define pow(a,b) pow((double)a,(int)b) #define inf (1<<29) #define NN 100005 using namespace std; const double PI = acos(-1.0); typedef long long LL; //一样的思想,暴力的遍历每一个可能的答案,check是否满足,找到满足的最小的,于是二分 int n,m;//n个数分m组 int a[NN]; bool ok(int ans)//判断答案能否分m组 { //........分组连续......贪心,只要连续的加起来没有超过ans就可以分到一个组 int k = 1;//傻了... for (int i = 0,sun = 0;i < n;i++) { if (sun + a[i] <= ans) sun += a[i]; else { k++; if (k > m) return 0;//剪枝 sun = a[i]; } } return k <= m;//能分6组的话分7组是绰绰有余滴,小于m组的也可以分成m组 } int main() { while (~scanf("%d%d",&n,&m)) { int l = 0,r = 0; for (int i = 0;i < n;i++) { scanf("%d",a+i); r += a[i]; l = max(l,a[i]); } int mid = (l+r)>>1; while (l < r) { if (ok(mid))//OK只说明mid满足 但是不一定最小 r = mid - 1;//尝试更小的mid else l = mid + 1;//不满足就尝试更大的mid mid = (l+r)>>1; } cout<<mid<<endl; } return 0; }
相关文章推荐
- CSS轮廓outline
- spark 编程向导
- sed命令用法
- 反转链表——递归实现
- gulp-css-spriter 雪碧图合成
- UITextField的键盘(格式化设置)
- SpingAOP源码研究
- 质数筛选
- Python回顾与整理3:数字
- Python回顾与整理3:数字
- Storm集群的搭建
- 【你不知道的JavaScript(上)读书笔记】第1章:作用域
- 阿里云 Ubuntu安装vncserver实现图形化访问
- Oracle读取excel
- 虚拟地球原理与实现
- 【你不知道的JavaScript(上)读书笔记】第2章:词法作用域
- Android 进程常驻(2)----细数利用android系统机制的保活手段
- Python爬虫_获取贴吧内容
- solution Of Pat 1109. Group Photo (25)
- A标签使用javascript:伪协议