Juego de eliminación de matrices (enumeración binaria)

Enlace de título: https://ac.nowcoder.com/acm/problem/200190

Idea general

Para n * m matrices, Niu Mei puede eliminar una fila o una columna por operación y obtener el puntaje de la matriz de fila / columna. Por cierto, está borrado. En la mayoría de las k operaciones, puede preguntar cuál es el puntaje más alto puedes obtener.

1 <= n, m <= 15; 1 <= ai <= 1e6; 1 <= k <= n * m

Ideas

El rango dado por nym es muy pequeño y la enumeración binaria se puede realizar en las filas. Por ejemplo, 5 (101) significa eliminar las filas 1 y 3, y luego quedan k-2 operaciones, luego ordenar las sumas restantes de cada columna en orden, tomar el primer número grande k-2 para sumar y actualizar el valor máximo.

El juicio especial k es mayor o igual que el valor menor de nm, porque todos pueden eliminarse y la suma se puede generar directamente.

codigo ca

#include<bits/stdc++.h>
using namespace std;
#define io cin.tie(0);ios::sync_with_stdio(false);
#define ok(x, y) x >= 1 && x <= n && y >= 1 && y <= m
#define debug(x) cout<<#x<<"="<<x<<endl
#define lowbit(x) x&(-x)
#define pii pair<int,int>
#define mk make_pair
#define ll long long
#define ull unsigned long long
#define lb long double
#define rs p<<1|1
#define ls p<<1
#define eps 1e-6
#define pi acos(-1)
const int maxn = 1e5 + 5;
const int maxm = 1e6 + 5;
const int mod = 998244353;
const int inf = 0x3f3f3f3f;
const int bas = 2333;
inline ll read(){
    ll p=0,f=1;char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){p=(p<<1)+(p<<3)+(c^48),c=getchar();}
    return f*p;
}
void print(__int128 x){
    if(x<0) {putchar('-'); x=-x;}
    if (x>9) print(x/10);
    putchar('0'+x%10);
}


int a[25][25], sum[25], tmp[25];
void solve(){
    int n, m, k;
    cin >> n >> m >> k;
    memset(sum, 0, sizeof(sum));
    int ans = 0;
    for(int i = 0; i < n; i ++){
        for(int j = 0; j < m; j ++){
            cin >> a[i][j];
            sum[i] += a[i][j];//每行矩阵和
            ans += a[i][j];
        }
    }
    if(k >= min(n, m)){
        cout << ans << endl;
        return;
    }
    ans = 0;
    for(int t = 0; t < (1 << n); t ++){
        int cnt = 0, res = 0;
        for(int i = 0; i < n; i ++) cnt += (t>>i)&1;//二进制1的个数
        if(k - cnt < 0 || k - cnt > m) continue;//留给列的次数
        memset(tmp, 0, sizeof(tmp));
        for(int i = 0; i < n; i ++){
            if((t>>i)&1) res += sum[i]; //该行消去
            else for(int j = 0; j < m; j ++) tmp[j] += a[i][j]; //该列保留
        }
        sort(tmp, tmp + m, greater<int>());//从大到小排序
        for(int i = 0; i < k - cnt; i ++) res += tmp[i];
        ans = max(ans, res);
    }
    cout << ans << endl;
}

int main(){
    io;
    solve();
    return 0;
}

 

Supongo que te gusta

Origin blog.csdn.net/weixin_43911947/article/details/114196685
Recomendado
Clasificación