Codeforces 417D.Cunning Gena (状压DP)

Link to the original title The
small picture really wants to participate in the "Russian Cipher Cup" finals, or at least get a T-shirt. But the topic of the competition was too complicated, so he discussed with n friends to help him solve the problem. There are a total of m questions in the competition. The small picture knows the problems that every friend can solve. But his friend will not provide free help: the i-th friend asks Xiaotu to pay xi yuan. In addition, it is required that the computer of the small picture must be connected to at least ki monitors, and the price of each monitor is b yuan.

Xiaotu is very cautious about money, so he wants to spend as little money as possible to solve all the problems. Please help me with a bunch of small pictures and tell him the minimum amount of money to solve all the problems. Note that at the beginning there is no monitor connected to the small picture computer.

Input the
first line of Input three integers n, m, b (1 ≤ n ≤ 100; 1 ≤ m ≤ 20; 1 ≤ b ≤ 109), which respectively represent the number of friends in the small picture, the number of questions, and the cost of a monitor .

The next 2n rows of data entered describe the requirements of these friends. Lines 2i and (2i + 1) contain information about the i-th friend. The 2i row contains three integers xi, ki and mi (1 ≤ xi ≤ 109; 1 ≤ ki ≤ 109; 1 ≤ mi ≤ m), which respectively represent the amount of money the friend wants, the number of monitors and what he can solve The number of questions. The (2i + 1) line contains mi different positive integers, representing the number of the problem that the i-th friend can solve. The questions are numbered from 1 to m.

Output
small images to solve all the problems to spend the least money.

If there is no result that meets the condition, please output -1.

Examples
Input
2 2 1
100 1 1
2
100 2 1
1
Output
202
Input
3 2 5
100 1 1
1
100 1 1
2
200 1 2
1 2
Output
205
Input
1 2 1
1 1 1
1
Output
-1

Idea:
The range of m is very small, consider using binary to indicate whether a certain problem is solved.
dp[i] indicates the minimum cost of the display cost when the state is i, so it only needs to enumerate which states each friend can transfer. can.
Sort the number of monitors required by each friend, so that when the i-th person is enumerated, the required monitor cost is fixed.
Ll burst, to open ull.
Code:

#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll,ll>PLL;
typedef pair<int,int>PII;
typedef pair<double,double>PDD;
#define I_int ll
inline ll read()
{
    
    
    ll x=0,f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9')
    {
    
    
        if(ch=='-')f=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9')
    {
    
    
        x=x*10+ch-'0';
        ch=getchar();
    }
    return x*f;
}
#define read read()
#define closeSync ios::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define multiCase int T;cin>>T;for(int t=1;t<=T;t++)
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define repp(i,a,b) for(int i=(a);i<(b);i++)
#define per(i,a,b) for(int i=(a);i>=(b);i--)
#define perr(i,a,b) for(int i=(a);i>(b);i--)
ll ksm(ll a,ll b,ll p)
{
    
    
    ll res=1;
    while(b)
    {
    
    
        if(b&1)res=res*a%p;
        a=a*a%p;
        b>>=1;
    }
    return res;
}
#define PI acos(-1)
#define x first
#define y second
const int maxn=1e6+7,inf=0x3f3f3f3f;
struct node{
    
    
    ull x,k,m;
    ull s;
}a[110];
bool cmp(node a,node b){
    
    
    return a.k<b.k;///排序后枚举到第i个所需的显示器数量就是总的数量
}
ull dp[1<<21];///dp[i]表示当前状态是i时,所需要的最小花费(不计算显示器的花费)
int main()
{
    
    
    int n=read,m=read,b=read;
    for(int i=1;i<=n;i++){
    
    
        cin>>a[i].x>>a[i].k>>a[i].m;
        for(int j=0;j<a[i].m;j++){
    
    
            ull t;cin>>t;
            a[i].s|=1<<t-1;///记录每个人能够解决的问题数
        }
    }
    sort(a+1,a+1+n,cmp);
    dp[0]=0;
    for(int i=1;i<(1<<m);i++) dp[i]=1e19;
    ull res=1e19;
    for(int i=1;i<=n;i++){
    
    
        for(int j=0;j<(1<<m);j++)
            dp[j|a[i].s]=min(dp[j|a[i].s],dp[j]+a[i].x);
        res=min(res,dp[(1<<m)-1]+a[i].k*b);
    }
    if(res==1e19) puts("-1");
    else cout<<res<<endl;
    return 0;
}



Guess you like

Origin blog.csdn.net/weixin_45675097/article/details/114375944