链接:https://ac.nowcoder.com/acm/contest/946/B

来源:牛客网

时间限制:C/C++ 1秒,其他语言2秒

空间限制:C/C++ 262875K,其他语言525750K

64bit IO Format: %lld

题目描述

筱玛是一个热爱阅读的好筱玛,他最喜欢的事情就是去书店买书啦!

一天,他来到一家有

n

n本书的书店,筱玛十分快乐,决定把这家店里所有的书全部买下来。

正巧今天店里在搞促销活动,包含若干个促销方案。每个促销方案是由指定的若干本书构成的集合,如果购买了该方案中所有的书,那么其中最便宜的一本书将免费。但是,每本书只能用于一个促销方案。

作为店里的VIP,筱玛会得到

n

n个价格标签。筱玛可以给每本书挑选一个价格标签,使得每个价格标签和每本书一一对应。

筱玛想要知道,在合理利用所有促销方案的情况下,买下所有书最小要多少钱。

输入描述:

第一行两个数

n

,

m

n,m,分别表示书的本数和促销方案的种数。

第二行

n

n个整数,表示每个价格标签上的标注的价格。

接下来

m

m行,每行第一个数

k

k表示该促销方案包含书的数量。接下来

k

k个数,表示书的编号。

输出描述:

输出一行一个数,表示答案。

示例1

输入

复制

4 2

2 3 2 4

2 2 3

2 2 4

输出

复制

8

备注:

对于100%的数据,

1



n



15

,

1



m



2

n



1

1≤n≤15,1≤m≤2n−1,所有标签价值之和在

int

int范围内。

题意:



思路:



首先进行二进制状压,i代表的整数的二进制信息中的第i位为1,代表取第i位。

然后对读入的书价进行降序排序,

然后把m个方案数进行状压成now ,vis[now] =1 代表有now这个状态的优惠方案。

定义状压DP的状态,dp[i] 代表买了i状态的书,最多优惠多少元。

同时维护数组cnt[i] 代表 第i个状态买了几本书,即二进制状态中有多少个1,我们可以用dp来获得。

那么dp[i] 有三种更新方式,

1,有i这个优惠方案,那么dp[i] 的最小就可以优惠 a[cnt[i]] 元,(a是已排序后的数组)

2,多个状态的补集为i,例如 j^x=i,那么dp[i] 就可以由先使用j方案的优惠,取得了a[cnt[j] 优惠,然后再用 x方案,因为x方案是j关于i状态的补集,所以x,j方案都使用后,x方案可以获得的优惠是a[cnt[i]] 元。

3、一个不是在优惠方案中的数j,和其他状态来更新的。(这样可以确保每一个状态被更新到。)

所以书的价格和是sum,

那么 答案就是sum-dp[(1<<n)-1]

细节见代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <vector>
#include <iomanip>
#define ALL(x) (x).begin(), (x).end()
#define rt return
#define dll(x) scanf("%I64d",&x)
#define xll(x) printf("%I64d\n",x)
#define sz(a) int(a.size())
#define all(a) a.begin(), a.end()
#define rep(i,x,n) for(int i=x;i<n;i++)
#define repd(i,x,n) for(int i=x;i<=n;i++)
#define pii pair<int,int>
#define pll pair<long long ,long long>
#define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define MS0(X) memset((X), 0, sizeof((X)))
#define MSC0(X) memset((X), '\0', sizeof((X)))
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define eps 1e-6
#define gg(x) getInt(&x)
#define chu(x) cout<<"["<<#x<<" "<<(x)<<"]"<<endl
using namespace std;
typedef long long ll;
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
ll lcm(ll a,ll b){return a/gcd(a,b)*b;}
ll powmod(ll a,ll b,ll MOD){ll ans=1;while(b){if(b%2)ans=ans*a%MOD;a=a*a%MOD;b/=2;}return ans;}
inline void getInt(int* p);
const int maxn=1000010;
const int inf=0x3f3f3f3f;
/*** TEMPLATE CODE * * STARTS HERE ***/
ll a[50];
int n;
int m;
int vis[maxn];
int cnt[maxn];
ll dp[maxn];
int main()
{
// freopen("D:\\common_text\\code_stream\\in.txt","r",stdin);
//freopen("D:\\common_text\code_stream\\out.txt","w",stdout);
gbtb;
cin>>n;
cin>>m;
repd(i,1,n)
{
cin>>a[i];
}
sort(a+1,a+1+n,greater<ll>());
repd(i,1,m)
{
int k;
cin>>k;
int v;
int now=0;
repd(j,1,k)
{
cin>>v;
now|=(1<<(v-1));
}
vis[now]=1;
}
// dp[i]代表买了i状态的书,最多可以优惠多少元。
int maxstate=(1<<n)-1;// 最大二进制状态
for(int i=1;i<=maxstate;++i)
{
cnt[i]=cnt[i&(i-1)]+1;// dp 求cnt[i],cnt[i]代表i的二进制中有多少个1,从i-lowbit(i)转移
}
// repd(i,1,maxstate)
// {
// chu(cnt[i]);
// }
for(int i=0;i<=maxstate;++i)// 枚举所有二进制状态
{
if(vis[i])
dp[i]=max(dp[i],a[cnt[i]]);// 用i方案来免费第cnt[i]贵的书
// chu(i);
for(int j=i;j;j=i&(j-1))// 枚举i的所有子集j
{ int x=j^i;// x是 j关于i的补集
if(!vis[x])
continue;
dp[i]=max(dp[i],dp[j]+a[cnt[i]]);
// 因为 x^j=i,那么我们就用 x+j混合的方案来使得i状态的cnt[i]个书都买,最大优惠了dp[j]+a[cnt[i]]
}
for(int j=0;j<n;j++)// 尝试牺牲一本书(即全价买它),来保证更新所有状态
{
dp[i|(1<<j)]=max(dp[i|(1<<j)],dp[i]);
}
}
ll sum=0ll;
for(int i=1;i<=n;i++)
{
sum+=a[i];
}
// chu(dp[(1<<n)-1]);
cout<<sum-dp[(1<<n)-1]<<endl; return 0;
} inline void getInt(int* p) {
char ch;
do {
ch = getchar();
} while (ch == ' ' || ch == '\n');
if (ch == '-') {
*p = -(getchar() - '0');
while ((ch = getchar()) >= '0' && ch <= '9') {
*p = *p * 10 - ch + '0';
}
}
else {
*p = ch - '0';
while ((ch = getchar()) >= '0' && ch <= '9') {
*p = *p * 10 + ch - '0';
}
}
}

牛客练习赛49 B 筱玛爱阅读 (状压DP,子集生成)的更多相关文章

  1. 牛客练习赛49 E 筱玛爱游戏 (线性基+博弈)

    链接:https://ac.nowcoder.com/acm/contest/946/E 来源:牛客网 筱玛爱游戏 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 524288K,其他 ...

  2. 牛客练习赛B题 筱玛的排列(找递推规律)

    链接:https://ac.nowcoder.com/acm/contest/342/B来源:牛客网 筱玛的排列 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 524288K,其他语 ...

  3. 牛客练习赛 A题 筱玛的快乐

    链接:https://ac.nowcoder.com/acm/contest/342/A来源:牛客网 筱玛的快乐 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 524288K,其他语 ...

  4. 牛客练习赛22 简单瞎搞题(bitset优化dp)

    一共有 n个数,第 i 个数是 xi  xi 可以取 [li , ri] 中任意的一个值. 设 ,求 S 种类数. 输入描述: 第一行一个数 n. 然后 n 行,每行两个数表示 li,ri.   输出 ...

  5. 牛客练习赛3 F - 监视任务——贪心&&树状数组

    题目 链接 $Reki$ 在课余会接受一些民间的鹰眼类委托,即远距离的狙击监视防卫..$Reki$ 一共接收到$m$份委托,这些委托与 $n$ 个直线排布的监视点相关.第 $i$ 份委托的内容为:对于 ...

  6. 计蒜客习题:蒜头君的积木 (状压DP 枚举子集)

    问题描述 蒜头君酷爱搭积木,他用积木搭了 n 辆重量为 wi的小车和一艘最大载重量为 W 的小船,他想用这艘小船将 n 辆小车运输过河.每次小船运载的小车重量不能超过 W.另外,小船在运载小车时,每辆 ...

  7. 牛客练习赛53 A 超越学姐爱字符串 (DP)

    牛客练习赛53 超越学姐爱字符串 链接:https://ac.nowcoder.com/acm/contest/1114/A来源:牛客网 超越学姐非常喜欢自己的名字,以至于英文字母她只喜欢" ...

  8. 牛客练习赛37-筱玛的字符串-DP递推

    筱玛的字符串 思路 :dp [ i ] [ j ] [ 3 ] 分别代表到第 i 位时 左括号比右括号多 j ,后面有三个状态 分别表示当前位置 S3的字符 是正在反转的,还是 反转完成的,还是没有反 ...

  9. 【并查集缩点+tarjan无向图求桥】Where are you @牛客练习赛32 D

    目录 [并查集缩点+tarjan无向图求桥]Where are you @牛客练习赛32 D PROBLEM SOLUTION CODE [并查集缩点+tarjan无向图求桥]Where are yo ...

随机推荐

  1. Vue学习(一) :入门案例

    1. 开始前的准备 IDE:VSCode(推荐)或者Sublime Text 前导技术:JavaScript中级 2. 官方提供的product例程 product.html页面代码: <div ...

  2. SQL Server标量函数改写内联表值函数优化案例

    问题SQL: SELECT TOP 1001 ha.HuntApplicationID , ha.PartyNumber , mht.Name AS MasterHuntTypeName , htly ...

  3. Python基础面试题库

    Python基础面试题库   Python是一门学习曲线较为容易的编程语言,随着人工智能时代的到来,Python迎来了新一轮的高潮.目前,国内知乎.网易(游戏).腾讯(某些网站).搜狐(邮箱).金山. ...

  4. 【零售App】—— react/ant design mobile项目爬坑

    一.H5制作 - 图片文本的动画效果 bug:打开一个模板,添加图片,添加动画效果,若先选定动画效果,再调节动画时间和延迟时间,则动画和延迟时间没有改变:若先调节动画时间和延迟时间在选定动画效果,则动 ...

  5. 一、基础篇--1.1Java基础-final, finally, finalize 的区别

    final, finally, finalize 首先,这三个关键字没什么关联,只是放在一起比较像,用法用处完全不同. final: final关键字可以用来修饰类.方法.变量(成员变量和局部变量), ...

  6. java Map类

    实现类 类型区别 HashMap 最常用的Map,它根据键的HashCode 值存储数据,根据键可以直接获取它的值,具有很快的访问速度.HashMap最多只允许一条记录的键为Null(多条会覆盖);允 ...

  7. loj#6034 「雅礼集训 2017 Day2」线段游戏

    分析 区间李超树板子题 代码 #include<bits/stdc++.h> using namespace std; #define db double const int inf = ...

  8. 阶段3 1.Mybatis_05.使用Mybatis完成CRUD_1 回顾Mybatis的环境搭建-实现查询所有功能

    先回顾Mybits的环境搭建,. 直接next 直接点击finish 创建好的项目. 所有东西都自己写不现实,约束文件的头部还是拷贝过来 导入依赖坐标,Mybits mysql的驱动 log4j 单元 ...

  9. centos7:Kafka集群安装

    解压文件到安装目录 tar -zxvf kafka_2.10-0.10.2.1.tgz 1.进入目录 cd kafka_2.10-0.10.2.1 mkdir logs cd config cp se ...

  10. 【Linux开发】jpeglib使用指南

    您可以到www.ijg.org网站下载libjpeg的源码, IJG JPEG Library就是jpeg压缩库,是以源码的形式提供给软件开发人员的,当然在软件包里也有编译好的库文件,我们这里就只用到 ...