苦想无果,看了题解才勉强明白……用dp[i][st]表示选择了i个equipment所决定的属性的状态(i<=5,st<(1<<5))。具体dp的过程可以不用管到底选了那个equipment,通过枚举子集可以自动得出最优的,而重复选择并不与会引起冲突(因为一个equipment至多就决定5个属性)。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
#define M 10010
int n,k;
int a[M][5],dp[6][1<<5];
int main()
{
freopen("in.txt","r",stdin);
int T;
cin>>T;
while(T--)
{
cin>>n>>k;
for(int i=0;i<n;i++)
for(int j=0;j<5;j++)
cin>>a[i][j];
memset(dp,0,sizeof(dp));
k=min(k,5);
for(int i=1;i<=k;i++)
for(int j=0;j<(1<<5);j++)
{
for(int t=j;t;t=(t-1)&j)
{
int origin=j-t;
for(int x=0;x<n;x++)
{
int sum=0;
for(int y=0;y<5;y++) if(t&(1<<y)) sum+=a[x][y];
dp[i][j]=max(dp[i][j],dp[i-1][origin]+sum);
}
}
}
cout<<dp[k][(1<<5)-1]<<endl;
}
return 0;
}