记录编号 437910 评测结果 AAAAAAAAAA
题目名称 [USACO Mar07] 月度花费 最终得分 100
用户昵称 GravatarFisher. 是否通过 通过
代码语言 C++ 运行时间 0.020 s
提交时间 2017-08-14 21:08:01 内存使用 0.70 MiB
显示代码纯文本
  1. #include <iostream>
  2. #include <cstdio>
  3. #include <algorithm>
  4. using namespace std;
  5. /*
  6. 二分答案。
  7. 刚开始没想明白二分范围。其实就是最小的花费到总和就行了;
  8. 答案满足一个单调性;
  9. 验证很简单;
  10. */
  11. inline int read(){
  12. int x=0,f=1;char c=getchar();
  13. while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
  14. while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
  15. return x*f;
  16. }
  17. const int maxn=100010;
  18. int n,m;
  19. int l,r;
  20. int w[maxn];
  21. inline bool ok(int guess){//二分答案里最关键的;
  22. int f=1,s=0;//刚开始是一组,错了还能70分。。
  23. for(int i=1;i<=n;i++){
  24. if(w[i]>guess)return 0;//这里一定要注意...
  25. if(s+w[i]<=guess){s+=w[i];}
  26. else {f++;s=w[i];}
  27. }
  28. return f<=m?1:0;//分的组可以小于m因为可以再拆。
  29. }
  30. inline int erfen(){
  31. while(l+1<r){
  32. int mid=(l+r)>>1;
  33. if(ok(mid))r=mid;//不同的题这里也不同,详细可以比较《跳石子》。
  34. else l=mid;
  35. }
  36. if(ok(l))return l;
  37. else return r;
  38. }
  39. int main(){
  40. freopen("expense.in","r",stdin);
  41. freopen("expense.out","w",stdout);
  42. n=read();m=read();l=0x7fffffff;
  43. for(int i=1;i<=n;i++){w[i]=read();l=min(l,w[i]);r+=w[i];}
  44. printf("%d\n",erfen());
  45. return 0;
  46. }