UVA - 1508 Equipment DFS

来源:互联网 发布:什么是美工设计助理 编辑:程序博客网 时间:2024/06/05 15:00

题目大意:给出N个五元组和一个K,要求对这N个五元组进行合并,合并的规则如下

两个五元组进行合并的结果为一个五元组,新的五元组取这两个五元组相应位置的数的最大值为新的值,

如A1 = (10,20,40,30,50), A2 = (50,30,20,10,50),这两个五元组如果合并的话,新的五元组A3 = (50,30,40,30,50)

现在要求合并N个五元组中的k个,使得新的五元组的五个数的和最大


解题思路:

1.当K >= 5的话,比较简单,只需记录每个位置的最大值,然后进行相加即可。

2.当K < 5时,如果用0表示这个位置的数不取,1表示取的话,那么五元组就有31一种表示方法了,最终的结果是要11111这种情况,表示每个位置的数都要取到,这样的话记录每种情况下的最大值,然后再进行亦或运算,就可以得到结果了,具体请看代码

#include<cstdio>#include<cstring>#include<algorithm>using namespace std;#define INF 0x3f3f3f3f#define maxn 110#define maxm 10010int MAX[10];int num[maxm][10];int N, K;int statu[32];int dfs(int s, int cur) {if(cur == K)return 0;int temp = 0;for(int i = s; i; i = (i - 1) & s )temp = max(temp,statu[i] + dfs(s^i,cur+1));return temp;}int main() {int test;scanf("%d",&test);while(test--) {scanf("%d %d",&N, &K);memset(statu,0,sizeof(statu));memset(MAX,0,sizeof(MAX));for(int i = 0; i < N; i++) {for(int j = 0; j < 5; j++) {scanf("%d",&num[i][j]);MAX[j] = max(MAX[j],num[i][j]);}for(int j = 0; j < 32; j++) {int temp = 0;for(int k = 0; k < 5; k++)  if(j & (1 << k))temp += num[i][k];statu[j] = max(statu[j],temp);}}if(K >= 5) {int temp = 0;for(int i = 0; i < 5; i++)temp += MAX[i];printf("%d\n",temp);}else printf("%d\n",dfs(31,0));}return 0;}


0 0
原创粉丝点击