糖果(重复覆盖问题)【蓝桥杯】

糖果(重复覆盖问题)

题意

image-20201007122725364

思路

可以转化为简单的重复覆盖问题,我们用简单的状态压缩写

代码

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
#include<vector>
#include<stack>
#include<bitset>
#include<cstdlib>
#include<cmath>
#include<set>
#include<list>
#include<deque>
#include<map>
#include<queue>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define mst(s,_s) memset(s, _s, sizeof(s))
const double PI = acos(-1.0);
const double eps = 1e-6;
const int INF = 0x3f3f3f3f;
const int N = 1<<22;//注意数组要开大点
int T,n,m,k;

ll apple[N];
ll f[N];

int main() {
    cin>>n>>m>>k;
    for(int i=0;i<n;i++)
    {
        ll state=0;
        for(int i=0;i<k;i++){
            int a;
            cin>>a;
            a--;
            state|=1<<a;//注意这里要|=,不是+=
        }
        apple[i]=state;
    }
    
    for(int i=0;i<N;i++) f[i]=0x3f3f3f3f;
    f[0]=0;
    for(int state=0;state+1<1<<m;state++)
    {
        int x=0;
        for(int i=0;i<m;i++)
        {
            if(!(state>>i&1))
            {
                x=i;
                break;
            }
        }
        for(int j=0;j<n;j++)
        {
            if((apple[j]>>x&1))
            {
                f[state|apple[j]] = min(f[state|apple[j]] , f[state]+1);
               
            }
        }
    }
    ll n=1<<m;
    if(f[n-1]==0x3f3f3f3f) cout<<-1<<endl;
    else
        cout<<f[n-1]<<endl;
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值