题意:
给出n个5元组,求出其中k组,使得,每个数字最大的数的和最大值
首先分情况讨论:
这里主要是用了一个技巧:即用二进制来表示每个位子是否采用的情况,然后记录每个情况的最大值,最后组合最大值得到最优结果
如果k>=5,那么显然最大值就是每个位子上的最大值相加
如果不是,那么考虑所有串的所有情况的最大值,用一个数组记录每个情况的最大值,(实际上是不用担心串重复的),
代码:
#include<algorithm>
#include<cstring>
#include<string>
#include<iostream>
#include<cstdio>
using namespace std;
const int N = 10010;
int n, k;
int r[N][5], m[5], mmax[40];
int dfs(int s, int num) {
if(num == 0) return 0;
int temp = 0;
for(int s0=s; s0; s0=(s0-1)&s) {//s0是s的子集
temp = max(temp, mmax[s0]+dfs((s0^s), num-1));
}
return temp;
}
int main() {
int kase;
scanf("%d", &kase);
while(kase--) {
memset(m, 0, sizeof(m));
scanf("%d%d", &n, &k);
for(int i=0; i<n; i++)
for(int j=0; j<5; j++) {
scanf("%d", &r[i][j]);
m[j] = max(m[j], r[i][j]);
}
if(k >= 5) {
int sum = 0;
for(int i=0; i<5; i++) sum += m[i];
printf("%d\n", sum);
}
else {
memset(mmax, 0, sizeof(mmax));
for(int i=0; i<n; i++)
for(int j=0; j<=31; j++) {
int temp = 0;
for(int q=0; q<5; q++) {
if(j & (1<<q)) temp += r[i][q];
}
mmax[j] = max(mmax[j], temp);
}
printf("%d\n", dfs(31, k));
}
}
return 0;
}