codeforces 1209E1 Rotate Columns (easy version)

FRZ_29發表於2024-07-28

codeforces 1209E1 Rotate Columns (easy version)

題目傳送門:codeforccesluogu

思路

貪心,暴力搜尋

貪心

對於所有列,只有列中最大值在所有列的最大值中前 \(n\) 大才可能對答案有貢獻。
證明:若有非前 \(n\) 大的列對某行最大值產生了貢獻,則用沒有被取的前 \(n\) 大的列代替該行一定更優。所以只有列中最大值在所有列的最大值中前 \(n\) 大才可能對答案有貢獻。

暴力搜尋

將所有列按列的最大值從大到小排序。根據貪心,答案一定由前 \(n\) 列產生,而 \(n \leq 4\) ,所以直接爆搜就行了。

細節

更新的時候要先儲存,不然回溯會出錯。

程式碼

單次時間複雜度\(O(n^{2 \times n - 2})\)

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>

using namespace std;

const int N = 6, M = 105;

#define LF(i, __l, __r) for (int i = __l; i <= __r; i++)
#define RF(i, __r, __l) for (int i = __r; i >= __l; i--)

struct col { int a[N], mx; } a[M];
int t, n, m, ans, mx[N];
int back[N][N][N];

bool cmp(col a, col b) { return a.mx > b.mx; }

void Init() {
    ans = 0;
    memset(mx, 0, sizeof(mx));
    memset(back, 0, sizeof(back));
    memset(a, 0, sizeof(a));
}

void dfs(int u) {
    if (u == n + 2) {
        int res = 0;
        LF(i, 1, n) res += mx[i];
        ans = max(ans, res);
        return;
    }

    LF(i, 0, n - 1) {
        LF(j, 1, n) {
            int s = i + j;
            if (s > n) s %= n;
            back[u][i][s] = mx[s];
            mx[s] = max(mx[s], a[u].a[j]);
        }
        dfs(u + 1);
        LF(j, 1, n) mx[j] = back[u][i][j];
    }
}

int main() {
    scanf("%d", &t);

    while (t--) {
        Init();
        scanf("%d%d", &n, &m);
        LF(i, 1, n) LF(j, 1, m) {
            scanf("%d", &a[j].a[i]);
            a[j].mx = max(a[j].mx, a[j].a[i]);
        }

        sort(a + 1, a + m + 1, cmp);
        
        dfs(1);
        printf("%d\n", ans);
    }
    return 0;
}

相關文章