ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

黑龙江农垦科技职业学院喜迎寒假多校联赛2(快乐ak场)(D题详解)

2021-02-01 19:31:26  阅读:201  来源: 互联网

标签:cnt ak 多校 mid 划分 ull ans 喜迎 sum


黑龙江农垦科技职业学院喜迎寒假多校联赛2(快乐ak场)D题详解

从比赛到现在,终于算是想通了,记录一下。

AC代码

#include<iostream>

using namespace std;

typedef unsigned long long ull;

const int N = 1e6 + 10;

int n,m;
ull a[N],l,r;

bool check(ull mid)
{
   ull sum = 0;
   ull cnt = 1;
   for(int i = 0;i < n;i ++)
   {
   	sum += a[i];
   	if(sum > mid)
   	{
   		sum = a[i];
   		cnt ++;
   	}
   }
   if(cnt <= m)return true;
   return false;
}

int main()
{
   scanf("%d %d",&n,&m);
   for(int i = 0;i < n;i ++)
   {
   	scanf("%llu",&a[i]);
   	r += a[i];
   }
   //cout << check(6) << endl; 
   while(l < r)
   {
   	ull mid = (l + r) >> 1;
   	//mid >= m
   	if(check(mid))r = mid;
   	else l = mid + 1;
       //cout << "l = " << l << " r = " << r << endl; 
   }
   printf("%llu",l);
}

值得一提的是,这样写,就已经足够AC这个题,但是还有一处逻辑错误,二分的左边界应该是 m a x ( a [ i ] ) max(a[i]) max(a[i]),而不是0.

分析:

在这里插入图片描述

真正的划分过程如上,我们规定 m i d mid mid 这个数是能达到的最大值的最小值。这意味着 : 当 s u n < = m i d sun <= mid sun<=mid 的时候,都可以划分成一个队伍。如果 >sum,就记录得到的队伍数量 +1,这样的划分,使得 m i d mid mid向着 a n s ans ans不断靠近。
图中,从左往右,能组成 c n t cnt cnt支队伍的数量是在逐渐减少的。
如果拿个人max,来作为划分边界,毫无疑问的,能划分到n个队伍。 m i d mid mid从左往右能划分的队伍的数量越来越少,在ans处,恰好能划分成m,这也就是我们的答案,如果 > ans,肯定能划分成m支队伍,所以:

if(check(true)) r = mid;

是从这里转换的。

下面是个人错误的点

之所以迷了这么久,是因为划分的条件搞错了。在这里插入图片描述
之前我是这么划分的,导致更新区间一直是错误的状态。
能分成 m 队,这个是很容易做到的事情,因为在 mid = 个人最大 的时候,这个条件已经达成了。总实力的不断提高,能划分成的队伍肯定是越来越少的, > ans 组成一队,实际上 mid 的值是没有具体意义的,最后二分出来的值,肯定不是答案。

标签:cnt,ak,多校,mid,划分,ull,ans,喜迎,sum
来源: https://blog.csdn.net/m0_51990674/article/details/113527153

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有