1 条题解
-
0
C++ :
#include <cstdio> /* 回文数列:只能把相邻两个数合并成它们的和,求变成回文数列的最少合并次数。 双指针 i 从左、j 从右往中间扫: 两边当前值相等 -> 已经配对,i++、j--; 左边小 -> 把 a[i] 并进左边(a[i+1] += a[i]),合并次数 +1; 右边小 -> 把 a[j] 并进右边(a[j-1] += a[j]),合并次数 +1。 两侧的值是各自区间的前缀和/后缀和,永远是单调不减的, 较小的一侧不可能靠"等对面变大"而配上,只能继续合并,所以这个贪心是最优的。 n <= 1000000,值可达 1e9,合并后可达 1e15,需 O(n) + long long。 */ static long long a[1000005]; int main(){ int n; if(scanf("%d", &n) != 1) return 0; for(int i = 1; i <= n; i++) scanf("%lld", &a[i]); long long cnt = 0; for(int i = 1, j = n; i <= j; ){ if(a[i] == a[j]){ i++; j--; continue; } if(a[i] < a[j]){ a[i + 1] += a[i]; i++; cnt++; continue; } a[j - 1] += a[j]; j--; cnt++; } printf("%lld\n", cnt); return 0; }
- 1
信息
- ID
- 2839
- 时间
- 1000ms
- 内存
- 128MiB
- 难度
- (无)
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者