Equipment uva1508

来源:互联网 发布:怎么连接台湾的网络 编辑:程序博客网 时间:2024/06/08 04:28

题意:

给出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;}


0 0
原创粉丝点击