51nod 1625 夹克爷发红包

题目链接戳这里

题意是有一个赋有非负数的矩阵,每次可以将某一行or某一列替换成某个数值,可以替换<=k次,问如何替换能使得矩阵总和最大,输出最大值。

一开始想的是简单的贪心:比如找当前收益最大的行或者列来替换。这样的问题在于:替换行必然影响列,同理列影响行,就是说当前的贪心会影响之后的决策,不可行。

因为行最多10行,所以用dfs枚举行替换与否,然后再贪心地找收益最大的列来替换。


#include <bits/stdc++.h>
using namespace std;

#define ll long long
#define FOR(i,a,b) for(int i=(a);i<=(b);++i)
const ll maxN=2e2+5;
ll G[maxN][maxN], T[maxN][maxN], C[maxN];
bool used[maxN];
ll n, m, x, k, ans;

void calc() {
    ll us = 0;
    memcpy(T, G, sizeof G);
    FOR(i, 1, n) if (used[i]) {
        ++us;
        FOR(j, 1, m) T[i][j] = x;
    }
    ll sy = k - us;
    memset(C, 0, sizeof C);
    FOR(j, 1, m) FOR(i, 1, n) C[j] += T[i][j];

    ll aft = n * x;
    FOR(s, 1, sy) {
        ll idx = min_element(C + 1, C + 1 + m) - C;
        if (C[idx] >= aft) break;
        C[idx] = aft;
        FOR(i, 1, n) T[i][idx] = x;
    }

    ll t = 0;
    FOR(i, 1, n) FOR(j, 1, m) t += T[i][j];
    ans = max(ans, t);
}

void dfs(ll r, ll tk) {
    if (tk > k) return;
    if (r > n) calc();
    else {
        used[r] = 1;
        dfs(r + 1, tk + 1);
        used[r] = 0;
        dfs(r + 1, tk);
    }
}

int main () {
    cin >> n >> m >> x >> k;
    memset(used, 0, sizeof used);
    FOR(i, 1, n)
        FOR(j, 1, m) cin >> G[i][j];
    ans = 0;
    dfs(1, 0);
    cout << ans << '\n';
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/Rosebud/p/9765961.html