1. 程式人生 > 實用技巧 >D. Add to Neighbour and Remove - CF1462D

D. Add to Neighbour and Remove - CF1462D

codeforces1462D

題意:

給出一個由n個數組成的陣列,現在你可以對這個陣列進行如下操作:將陣列中的一個元素加到這個元素的兩邊中的一邊,然後將這個元素刪掉。若該元素在最左邊,那麼該元素不能加到左邊,因為它的左邊已經沒有元素了,同理最右邊。現在問你最少幾次這樣的操作可以讓整個陣列的每個元素都相等。

思路:

由於該題目的資料範圍並不是很大,只有\(1e3\),所以可以用\(n^2\)的做法得出結果:求出這個陣列的字首和,我們列舉前\(n\)個數作為最終陣列每個元素的大小,當找到第一個符合的字首和,也就是可以通過劃分這個陣列,讓這個陣列的每個部分和都是當前列舉的字首和的時候,可以保證其是最優解,當前的運算元就是答案。由於最差情況也可以通過全部合併得出,所以不存在沒有結果的情況。

ac程式碼:

#include <cstdio>
#include <cstring>

const int maxn = 3e3 + 5;

int a[maxn], pre[maxn];

int main () {
    int T, n;
    scanf ("%d", &T);
    while (T--) {
        scanf ("%d", &n);
        for (int i = 0; i < n; ++i) {
            scanf ("%d", &a[i]);
        }
        memset (pre, 0, sizeof pre);
        pre[0] = a[0];
        for (int i = 1; i < n; i++) {
            pre[i] = pre[i - 1] + a[i];
        }
        int ans = 0;
        for (int i = 0; i < n; i++) {
            int t = 0;
            bool flag = false;
            for (int j = 0; j < n; j++) {
                t = t + a[j];
                ans++;
                if (t == pre[i]) {
                    t = 0;
                    ans--;
                    if (j == n - 1) flag = true;
                } else if (t > pre[i]) break;
            }
            if (flag) break;
            else ans = 0;
        }
        printf ("%d\n", ans);
    }
    return 0;
}