题目入口
状压dp例题,| 二进制取反, > 二进制左移,学到了 写出来状态方程就行了
```cpp #include<bits/stdc++.h> using namespace std; #define ll long long using namespace std; const int maxn=(1<<21); int dp[maxn],candy[1000]; int main(){ int n,m,k; int i,j; int a; //dp[i]表示在i这种状态下最少的糖的包数; cin>>n>>m>>k; for(i=0;i<n;i++){ for(j=0;j<k;j++){ cin>>a; candy[i]|=1<<(a-1); } cout << candy[i] << endl; dp[candy[i]]=1;//此状态加入了要多加一包糖 } for(i=0;i<n;i++){ for(j=1;j<=(1<<m);j++){ if(dp[j]==0) continue;//如果这种状态在先前不存在,是不能转移的 if(dp[j|candy[i]]==0||dp[j|candy[i]]>dp[j]+1){ dp[j|candy[i]]=dp[j]+1; /* /*至少需要dp[j]包糖果,我再加上此时的第i包糖果,新的状态可能不存在,那么 这个新的状态就需要dp[j]+1包糖果;如果加上此时的第i包糖果,新的状态存在 了,那就得比较比较所需的糖果谁的少,取少的。*/ } } } if(dp[(1<<m)-1]!=0){ cout<<dp[(1<<m)-1]<<endl; } else{ cout<<-1<<endl; } return 0; }