/*
排序消除后效性,使得monitor的状态能提取出来
然后就是状态压缩Dp一下
dp[1<<20]定义为当前可以做哪些题的最小花费。
然后简单递推下,结果加上monitor所需的花费取最小值就是答案
*/
#pragma comment(linker,"/STACK:102400000,102400000")
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <set>
#include <map>
#include <vector>
#include <queue>
#include <ctime>
#include <cmath>
#include <cassert>
#include <stack>
#define MP make_pair
#define PB push_back
#define SZ(x) (int)x.size()
#define INF 1<<29
#define pii pair<int,int>
#define pll pair<LL,LL>
#define pdd pair<double,double>
#define vi vector<int>
#define L(x) x<<1
#define R(x) x<<1|1
#if(_WIN32||__WIN32__)
#define LL __int64
#define ll I64
#else
#define LL long long
#endif
//#define Local
using namespace std;
LL dp[1<<20];
struct Node
{
int money,monitor,statu;
}a[110];
bool cmp(Node a,Node b)
{
return a.monitor<b.monitor;
}
int n,m,b;
int main()
{
scanf("%d %d %d",&n,&m,&b);
for(int i=0;i<n;i++)
{
int x,y,__;
scanf("%d %d %d",&x,&y,&__);
a[i]=(Node){x,y,0};
while(__--)
{
int val;
scanf("%d",&val);
a[i].statu|=1<<(val-1);
}
}
sort(a,a+n,cmp);
for(int j=0;j<(1<<m);j++)
dp[j]=1ll<<60;
dp[0]=0;
LL Min=1ll<<60;
for(int i=0;i<n;i++)
{
for(int j=0;j<(1<<m);j++)
{
if(dp[j]+a[i].money<dp[j|a[i].statu])
dp[j|a[i].statu]=dp[j]+a[i].money;
}
LL sum=dp[(1<<m)-1]+(LL)a[i].monitor*b;
Min=min(Min,sum);
}
if(Min==1ll<<60)
Min=-1;
cout<<Min<<endl;
return 0;
}
RCC 2014 Warmup (Div. 2) D. Cunning Gena
最新推荐文章于 2014-04-23 15:42:00 发布