AcWing1243 糖果
思路:
状压dp。每组糖果用二进制数表示,0表示有,1表示没。预处理一下。dp[j|a[i]]=min(dp[j|a[i]],dp[j]+a[i])。
代码:
#include<bits/stdc++.h>
#define pii pair<int,int>
#define ll long long
const int N=1e6+10;
const int mod=1e7+9;
const int maxn=0x3f3f3f3f;
const int minn=0xc0c0c0c0;
const int inf=99999999;
using namespace std;
ll dp[1<<21],a[110]={0},s[30],n,m,k,l=0;
void change()
{
ll p=0,i;
for(i=1;i<=k;i++)
p=p|(1<<(s[i]-1));
a[++l]=p;
dp[p]=1;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
ll i,j,ask=0;
cin>>n>>m>>k;
ask=(1<<m)-1;
for(i=1;i<=ask;i++)
dp[i]=inf;
for(i=1;i<=n;i++)
{
for(j=1;j<=k;j++)
cin>>s[j];
change();
}
for(i=1;i<=l;i++)
for(j=0;j<=ask;j++)
dp[j|a[i]]=min(dp[j|a[i]],dp[j]+dp[a[i]]);
if(dp[ask]>=inf)
cout<<-1<<endl;
else
cout<<dp[ask]<<endl;
return 0;
}