#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。太爽了,自己想到的感觉是不一样
点赞 评论

相关推荐

牛客网
牛客企业服务