【任务分配】解题报告

来源:互联网 发布:c 变量已被优化掉 编辑:程序博客网 时间:2024/05/16 14:30

题目描述

图书馆按顺序排列有N本书需要维护,每本书的总页数不相同。现有M位员工。可以给每个员工分配连续的一段书籍,让他进行维护。现在的问题是,怎么样分配,工作任务最重(需要维护的页数最多)的人维护的页数尽量少。

【数据规模和约定】
N<=10^5,M<=N。一本书的页数最多10^4。

输入格式

第一行两个数,N、M。接下来N行,每行一个整数,表示一本书的页数。

输出格式

任务最重的人最少需要维护的页数。


rqnoj十月苦情赛。

终于AC了。。。内牛满面,感觉很简单的一道题,前两天考过的书稿复制和这个一模一样,结果还是wa10了。

错误完全在can()模块里面。重新打了一遍就好了,感觉基本功不是很扎实。。。还有一点,只要思路清晰,每一步尽量避免可能出错的写法,就会好得多,特别是边界模糊等一定要避免。

比如if (s>mid){j--;}这句话,一开始没有写s>mid这个判断条件,就多了些出错的可能,相似的地方就是尽量多用并列结构,少用嵌套结构。

还有s<=mid这一句,一开始写的s+page[i+1]<=mid,就是当前阶段考虑到了后面阶段的东西,很容易写错。。。思路清晰之后就避免了这些情况

#include <iostream>using std::cout;//using std::cin;#include <cstdio>typedef long long lld;const long oo = 0x7fff0000;long n;long m;long page[100002];lld sum;lld mid=oo;/*int bigger(const void* a,const void* b){long aa = *(long*)a;long bb = *(long*)b;if (aa>bb) return 1;if (aa<bb) return -1;return 0;}*/bool can(){long s = 0;long j = 1;for (long i=1;i<m+1;i++){s = 0;while (s<=mid&&j<=n){s += page[j];j++;}if (s>mid){j--;}if (j==n+1&&s<=mid){return true;}}return false;}int main(){freopen("rqnoj651.in","r",stdin);freopen("ans.out","w",stdout);scanf("%ld%ld",&n,&m);long mmax = 0;for (long i=1;i<n+1;i++){scanf("%ld",page+i);mmax >?= page[i];sum += page[i];}lld ans = oo;lld l = mmax;lld r = sum;while (l<=r){mid = (l+r)>>1;if (can()){if (ans>mid){ans = mid;}r = mid-1;}else l = mid+1;}cout << ans;return 0;}

原创粉丝点击