UVA 1508

题意:  已知n个5元组,从中选出k组,使得这些组中5个位置,每个位置上最大数之和最大。

分析:当k>5时,就是n个5元组最大的数之和,当k<5时,就当做5元组,状态压缩,用00000表示未选出5个最大值,11111表示已经选出了5个最大值,那么情况就一共有32种,然后枚举每种情况更新f[i][j]数组,f[i][j]数组储存选i组情况是j的最大值之和是多少,结果就是f[k][31]。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
 6 
 7 int a[10010][6],f[6][40];
 8 
 9 int main()
10 {
11     int t,n,k;
12     scanf("%d", &t);
13     while(t--)
14     {
15         scanf("%d%d",&n,&k);
16         for(int i=0;i<n;++i)
17             for(int j=0;j<5;++j)
18                 scanf("%d",&a[i][j]);
19         k=min(k,5);
20         memset(f,0,sizeof(f));
21         for(int i=1;i<=k;++i)
22             for (int j=0;j<32;++j)
23                 for(int x=j;x;x=(x-1)&j)
24                 {
25                     int tmp=j-x;
26                     for(int l=0;l<n;++l)
27                     {
28                         int sum=0;
29                         for(int m=0;m<5;m++)
30                             if(x&(1<<m))
31                                 sum+=a[l][m];
32                         f[i][j]=max(f[i][j],f[i-1][tmp]+sum);
33                     }
34                 }
35         printf("%d
",f[k][31]);
36     }
37     return 0;
38 }
原文地址:https://www.cnblogs.com/sunshinemxh/p/4842386.html