1 条题解

  • 0
    @ 2026-9-30 12:58:25

    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
    上传者