//2019糖果(状态压缩dp)
#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for(int i=(a);i<=(b);(i++))
int dp[1<<20];//其下标表示口味状态,其元素表示达到该口味状态所需要的最少袋数
int main(){
set<int> all;
int n,m,k;
cin>>n>>m>>k;
rep(j,1,(1<<m)-1) dp[j]=n+1;//初始化给其赋一个大值
dp[0]=0;
int a[n+1];
int x,b;
rep(i,1,n){
x=0;
rep(j,1,k){
cin>>b;
all.insert(b);//把有的口味记录起来
x|=1<<(b-1);//第b个口味存在,改为1
}
a[i]=x;//用一个数表示一袋糖果,其二进制01序列表示了其带内有哪几个口味,实现了状态压缩
}
if(all.size()<m)//set元素不重复,如果所有口味都不够m种,则“-1”
cout<<"-1"<<endl;
rep(i,1,n){
rep(j,0,(1<<m)-1){
int state=j;
if(dp[state]>100) continue;
int to=a[i]|state;//买了这袋糖果后,有了新的口味状态,用位操作实现状态转移
dp[to]=min(dp[to],dp[state]+1);//取最少的袋数就行
}
}
cout<<dp[(1<<m)-1]<<endl;
rep(i,0,(1<<m)-1) cout<<dp[i];
return 0;
}
/*样例输入
6 5 3
1 1 2
1 2 3
1 1 3
2 3 5
5 4 2
5 1 2
*/
2019糖果(状态压缩dp)
最新推荐文章于 2024-08-29 11:55:07 发布