AcWing 4366. 上课睡觉
AcWing 4366. 上课睡觉
好久没写题,一写就发现脑子生锈了(。
题目描述
有 堆石子,每堆的石子数量分别为 。
你可以对石子堆进行合并操作,将两个相邻的石子堆合并为一个石子堆,例如,如果 ,合并第 堆石子,则石子堆集合变为 。
我们希望通过尽可能少的操作,使得石子堆集合中的每堆石子的数量都相同。
请你输出所需的最少操作次数。
本题一定有解,因为可以将所有石子堆合并为一堆。
题意
这道题我初步的理解是,要划分出若干个区间,其中每个区间都是连续的,并且每个区间的石子数量和相等,求最小的合并次数,也就是最多的区间数量。
大佬的翻译是这样的:
给你一个长度为 的数组 ,相邻的两个元素可以合并成一个元素。设合并完每个元素都相等的数组 长度为 ,求 。
解题思路
我一上来想到的就是暴力枚举,但是我的暴力比大佬们的要更简陋,因为缺少了进一步挖掘题意,并且没有根据数据范围作进一步的思考。
我的思路:
-
从左到右枚举。
-
首先枚举第一个区间,即固定第一个元素为左端点,枚举其右端点,之后即可每个区间的和,即每堆石子的个数。
-
上述右端点右边的元素即第二个区间的左端点,此时继续枚举,目的是找到合法右端点,使得区间和为。
- 若找到,则依次类推继续第三个等;
- 若未找到,则更改第一个区间的右端点。
(由于元素非负,则这个区间和递增,若后续区间和达不到这个值,则可认为找不到)
-
处理特殊情况。。。
-
时间复杂度应该是
由于数据范围是,因此复杂度大概是,也就是说我的做法需要将一个维度优化至。(也许可能得推翻重来)
优化的思路:
根据题意,由于合并之后每堆石子的个数都相同,设堆数为,则每堆的石子数则为。这个式子说明, 是 的因数。也就是说,没有必要以的复杂度枚举第一个区间的右端点来得到,而是枚举 的因数,或者说用这个性质作为条件进行优化。具体如下:
- 从左到右枚举
- 枚举,可以是从到,也可以像上面那个思路那样枚举右端点再计算
- 判断是否为的因数,否,则继续枚举
- 依次判断能否合并为区间和为的区间,直到最后
- 在过程当中统计一下合并次数
- 特殊情况
代码
// Problem: 上课睡觉 // Contest: AcWing // URL: https://www.acwing.com/problem/content/description/4369/ // Memory Limit: 64 MB // Time Limit: 1000 ms // // Powered by CP Editor (https://cpeditor.org) #include <iostream> #include <cstring> #include <algorithm> using namespace std; const int N = 100010; int T, n; int a[N], s[N]; int main(void){ ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); cin >> T; while(T -- ) { cin >> n; for (int i = 1; i <= n; i ++ ) { cin >> a[i]; s[i] = s[i - 1] + a[i]; } int ans = 0, flag = 0, tepAns = 0; for (int i = 1; i <= n; i ++ ) { int sum = s[i] - s[0]; if (sum && s[n] % sum) continue; // 优化:sum 是所有石子数量之和的因数 tepAns = i - 1; // 第一堆石子的合并次数 int left = i + 1; for (int right = left; right <= n; right ++ ) { int tepSum = s[right] - s[left - 1]; if (tepSum == sum) { // 判断后续区间石子和是否等于 sum if (right != left) tepAns += right - left;// 只有一个元素的区间不需要合并 left = right + 1; right = left - 1; continue; } if (tepSum > sum) { // 小优化,由于tepSum单增,大于sum就可以结束 break; } } if (left == n + 1) { ans = tepAns; break; } } cout << ans << endl; } return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】