CF417D--- Cunning Gena(排序+状压dp)

A boy named Gena really wants to get to the “Russian Code Cup” finals, or at least get a t-shirt. But the offered problems are too complex, so he made an arrangement with his n friends that they will solve the problems for him.

The participants are offered m problems on the contest. For each friend, Gena knows what problems he can solve. But Gena’s friends won’t agree to help Gena for nothing: the i-th friend asks Gena xi rubles for his help in solving all the problems he can. Also, the friend agreed to write a code for Gena only if Gena’s computer is connected to at least ki monitors, each monitor costs b rubles.

Gena is careful with money, so he wants to spend as little money as possible to solve all the problems. Help Gena, tell him how to spend the smallest possible amount of money. Initially, there’s no monitors connected to Gena’s computer.

Input

The first line contains three integers n, m and b (1?≤?n?≤?100; 1?≤?m?≤?20; 1?≤?b?≤?109) — the number of Gena’s friends, the number of problems and the cost of a single monitor.

The following 2n lines describe the friends. Lines number 2i and (2i?+?1) contain the information about the i-th friend. The 2i-th line contains three integers xi, ki and mi (1?≤?xi?≤?109; 1?≤?ki?≤?109; 1?≤?mi?≤?m) — the desired amount of money, monitors and the number of problems the friend can solve. The (2i?+?1)-th line contains mi distinct positive integers — the numbers of problems that the i-th friend can solve. The problems are numbered from 1 to m.

Output

Print the minimum amount of money Gena needs to spend to solve all the problems. Or print -1, if this cannot be achieved.

Sample test(s)

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

看到m那么小,就直接想到状压dp了,但是这里有一个monitors的限制,不能暴力枚举这个值

可以先把输入数据按每一个人的monitors排序,这样从小到大枚举每一个人,边递推边记录了答案就行

/*************************************************************************
    > File Name: CF417D.cpp
    > Author: ALex
    > Mail: [email protected]
    > Created Time: 2015年03月16日 星期一 12时33分11秒
 ************************************************************************/

#include <map>
#include <set>
#include <queue>
#include <stack>
#include <vector>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;

const double pi = acos(-1.0);
const long long inf = (1LL << 60);
const double eps = 1e-15;
typedef long long LL;
typedef pair <int, int> PLL;

LL dp[(1 << 20) + 10];

struct node
{
    int sta;
    int cost;
    int num;
}fri[110];

int cmp (node a, node b)
{
    return a.num < b.num;
}

int main ()
{
    int n, m, b;
    while (~scanf("%d%d%d", &n, &m, &b))
    {
        for (int i = 0; i <= (1 << m); ++i)
        {
            dp[i] = inf;
        }
        dp[0] = 0;
        for (int i = 1; i <= n; ++i)
        {
            int cnt;
            fri[i].sta = 0;
            int x;
            scanf("%d%d%d", &fri[i].cost, &fri[i].num, &cnt);
            for (int j = 0; j < cnt; ++j)
            {
                scanf("%d", &x);
                fri[i].sta |= (1 << (x - 1));
            }
        }
        LL ans= inf;
        sort (fri + 1, fri + 1 + n, cmp);
        for (int i = 1; i <= n; ++i)
        {
            for (int j = 0; j < (1 << m); ++j)
            {
                dp[j | fri[i].sta] = min (dp[j] + fri[i].cost, dp[j | fri[i].sta]);
            }
            ans = min (ans, dp[(1 << m) - 1] + (LL)fri[i].num * b);
        }
        if (ans >= inf)
        {
            printf("-1\n");
        }
        else
        {
            cout << ans << endl;
        }
    }
    return 0;
}
时间: 2024-08-01 12:34:04

CF417D--- Cunning Gena(排序+状压dp)的相关文章

codeforce 417D Cunning Gena (状压DP)

原题地址:http://codeforces.com/problemset/problem/417/D 题意: Gena 为了解决m个问题,请他的朋友们帮忙,其中第i个朋友可以解决某mi个问题,需要花费xi卢布,并且要求安装至少ki个显示器,每个显示器需要b卢布. 问解决所有问题需要多少多少卢布 题解 考虑问题数目很小,可以状压DP. dp[S]表示当前状态的最优解,通过位运算进行转移. 考虑|没有逆运算,所以只能正推更新. 首先把朋友按照k排序,避免k的干扰. dp[][0]和dp[][1]分

COdeforces#417D Cunning Gena(状压DP)

A boy named Gena really wants to get to the "Russian Code Cup" finals, or at least get a t-shirt. But the offered problems are too complex, so he made an arrangement with his n friends that they will solve the problems for him. The participants

【BZOJ2064】分裂 状压DP

[BZOJ2064]分裂 Description 背景:和久必分,分久必和...题目描述:中国历史上上分分和和次数非常多..通读中国历史的WJMZBMR表示毫无压力.同时经常搞OI的他把这个变成了一个数学模型.假设中国的国土总和是不变的.每个国家都可以用他的国土面积代替,又两种可能,一种是两个国家合并为1个,那么新国家的面积为两者之和.一种是一个国家分裂为2个,那么2个新国家的面积之和为原国家的面积. WJMZBMR现在知道了很遥远的过去中国的状态,又知道了中国现在的状态,想知道至少要几次操作(

ZOJ 3306 状压dp

转自:http://blog.csdn.net/a497406594/article/details/38442893 Kill the Monsters Time Limit: 7 Seconds Memory Limit: 32768 KB In order to celebrate the 8th anniversary of ZOJ, watashi introduces a strange game to other ZJU ACM team members. The board of

[POJ1038]状压DP

题意:给一个n*m的区域,里面有一些障碍物,往里面放2*3和3*2的矩形,矩形之间不能重叠,不能覆盖到障碍物,求能放置的最大个数.(n<=150,m<=10) 思路:看到m=10就应该往状压dp方面想了.由于有3*2的矩形,所以需要记录2行的状态,粗略估计状态数高达150*2^20=1.5*1e8,这么多状态必然超时,注意到如果(i-1,j)为0了,无论(i,j)为1或0,(i,j)都不能放矩形,于是知道有很多无用的或者说不合法的状态,两行的状态用m位3进制数表示同样能实现转移.由于3进制数操

【弱校胡策】2016.4.14 (bzoj2164)最短路+状压DP+矩阵乘法+高斯消元+树链剖分+线段树+背包DP

cyyz&qhyz&lwyz&gryz弱校胡策 命题人:cyyz ws_fqk T3暴力写挫了 50+10+0滚粗辣! 奇妙的约会(appointment.cpp/c/pas) [问题描述] DQS和sxb在网上结识后成为了非常好的朋友,并且都有着惊人 的OI水平.在NOI2333的比赛中,两人均拿到了金牌,并保送进入 HU/PKU.于是两人决定在这喜大普奔的时刻进行面基. NOI2333参赛选手众多,所以安排了n个考点,DQS在1号考点, 而sxb在n号考点.由于是举办全国性赛事

HDU 5135 Little Zu Chongzhi&#39;s Triangles(状压dp或者贪心)

题目大意:给你n个线段让你任意组成三角形,求组出来的三角形的面积的和最大为多少. 解题思路:首先你得知道海伦公式:S = sqrt(p*(p-a)*(p-b)*(p-c)), p = (a+b+c)/2. 思路一:贪心,按照边的长度进行排序,从大到小判断如果可以构成三角形,就让他构成三角形,这样组成的三角形的面积和一定是最大的. 思路二:状压dp,先暴力求出来所有可以组成的三角形对应的状态和面积,然后dp求解,状态转移公式是:dp[i|(f[j].xnum)] = max(dp[i|(f[j].

【bzoj3717】[PA2014]Pakowanie 状压dp

题目描述 你有n个物品和m个包.物品有重量,且不可被分割:包也有各自的容量.要把所有物品装入包中,至少需要几个包? 输入 第一行两个整数n,m(1<=n<=24,1<=m<=100),表示物品和包的数量.第二行有n个整数a[1],a[2],…,a[n](1<=a[i]<=10^8),分别表示物品的重量.第三行有m个整数c[1],c[2],…,c[m](1<=c[i]<=10^8),分别表示包的容量. 输出 如果能够装下,输出一个整数表示最少使用包的数目.若不

JZYZOJ 1388 旅游 状压dp

http://172.20.6.3/Problem_Show.asp?id=1388 求拓扑排序方案数 状压dp,最开始以为是拓扑排序加数论或者搜索,没想到是状压dp,突然气死.jpg: 完全没有想到状态转移的方法,syq大佬太神了orz: 写的时候太沉迷与topsort对人顺序的分组类似于斯特林数求方案数(后来发现不是),忘了最原始的满足条件(事件a在事件b前完成)即可增加方案数的简单dp--(惭愧) 所以正解就是按dp进行顺序向状态里加人,对人实现排序,显然如果必须在a前的人都加到队列里了(