#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f3f3f
const int N=1<<16;
#define ll long long
int a[20],dp[N],v[N];
int dfs(int st,int now)
{
if(~dp[st])return dp[st];
int ans=0;
for(int s=st; s; s=(s-1)&st)
if(v[s])ans=max(dfs(st-s,now+v[s])+a[now+v[s]],ans);
return dp[st]=ans;
}
int main()
{
int n,m,s=0;
cin>>n>>m;
for(int i=0; i<n; i++)
cin>>a[i],s+=a[i];
sort(a,a+n,greater<int>());
for(int i=0; i<m; i++)
{
int x,y;
cin>>x;
int st=0;
for(int j=0; j<x; j++)
{
cin>>y;
y--;
st|=(1<<y);
}
v[st]=x;
}
memset(dp,-1,sizeof dp);
s-=dfs((1<<n)-1,-1);
cout<<s<<endl;
}
一开始想通过m个状态来组合出最优的,想到m^2都不能跑就觉得好难。后来经过提示复杂度O(3^n)后,才想到枚举子集的子集。反过来确定是否有m。太爽了,自己想到的感觉是不一样