题意:你有一个字符串, 有两种操作,一种是改变字符串,一种是某个用户询问这个字符串,如果一个用户每次查询字符串的时候都是他的用户名,他就会高兴。问最多有多少个用户会高兴?

题意:容易发现,在两个1操作之间,如果有多个用户的的询问,只能满足一个。换句话说,如果满足了其中的一个,那么其它的便不能满足。我们可以对所有两个1之间的操作两两连边,那么问题就变成了最大独立集问题。

对于这个问题,可以用状压DP解决,但是最多有40个不同的用户,所以需要分成两半,分别预处理,然后枚举其中的一半,在保证于这边一半不相交的情况下,找到对应的另一半。

代码:

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. int f[1 << 20], g[1 << 20];
  4. map<string, int> mp;
  5. int G[50][50];
  6. vector<int> v;
  7. int cnt;
  8. string s;
  9. int main() {
  10. int n, m, op;
  11. scanf("%d%d", &n, &m);
  12. for (int i = 1; i <= n; i++) {
  13. scanf("%d", &op);
  14. if (op == 1) {
  15. v.clear();
  16. continue;
  17. } else {
  18. cin >> s;
  19. if(!mp.count(s))
  20. mp[s] = cnt++;
  21. v.push_back(mp[s]);
  22. for (int j = 0; j < v.size() - 1; j++)
  23. G[v[j]][v[v.size() - 1]] = G[v[v.size() - 1]][v[j]] = 1;
  24. }
  25. }
  26. if(v.size()) {
  27. for (int j = 0; j < v.size() - 1; j++)
  28. G[v[j]][v[v.size() - 1]] = G[v[v.size() - 1]][v[j]] = 1;
  29. }
  30. int s1 = m / 2;
  31. int s2 = m - s1;
  32. for (int i = 0; i < (1 << s1); i++) {
  33. for (int j = 0; j < s1; j++) {
  34. if(((i >> j) & 1) == 0) {
  35. int flag = 1;
  36. for (int k = 0; k < s1; k++) {
  37. if((i >> k) & 1)
  38. if(G[j][k] == 1) {
  39. flag = 0;
  40. break;
  41. }
  42. }
  43. f[i | (1 << j)] = max(f[i | (1 << j)], f[i] + flag);
  44. }
  45. }
  46. }
  47. for (int i = 0; i < (1 << s2); i++) {
  48. for (int j = 0; j < s2; j++) {
  49. if(((i >> j) & 1) == 0) {
  50. int flag = 1;
  51. for (int k = 0; k < s2; k++) {
  52. if((i >> k) & 1)
  53. if(G[j + s1][k + s1] == 1) {
  54. flag = 0;
  55. break;
  56. }
  57. }
  58. g[i | (1 << j)] = max(g[i | (1 << j)], g[i] + flag);
  59. }
  60. }
  61. }
  62. int ans = 0;
  63. for (int i = 0; i < (1 << s1); i++) {
  64. int now = (1 << s2) - 1;
  65. for (int j = 0; j < s2; j++) {
  66. for (int k = 0; k < s1; k++) {
  67. if((i >> k) & 1)
  68. if(G[k][j + s1] == 1) {
  69. now ^= (1 << j);
  70. break;
  71. }
  72. }
  73. }
  74. ans = max(ans, f[i] + g[now]);
  75. }
  76. printf("%d\n", ans);
  77. }

  

Codeforces 1105E 最大独立集 状态DP 中途相遇法的更多相关文章

  1. Codeforces 525E Anya and Cubes 中途相遇法

    题目链接:点击打开链接 题意: 给定n个数.k个感叹号,常数S 以下给出这n个数. 目标: 随意给当中一些数变成阶乘.至多变k个. 再随意取一些数,使得这些数和恰好为S 问有多少方法. 思路: 三进制 ...

  2. 【中途相遇法】【STL】BAPC2014 K Key to Knowledge (Codeforces GYM 100526)

    题目链接: http://codeforces.com/gym/100526 http://acm.hunnu.edu.cn/online/?action=problem&type=show& ...

  3. uva 6757 Cup of Cowards(中途相遇法,貌似)

    uva 6757 Cup of CowardsCup of Cowards (CoC) is a role playing game that has 5 different characters (M ...

  4. LA 2965 Jurassic Remains (中途相遇法)

    Jurassic Remains Paleontologists in Siberia have recently found a number of fragments of Jurassic pe ...

  5. HDU 5936 Difference 【中途相遇法】(2016年中国大学生程序设计竞赛(杭州))

    Difference Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total ...

  6. 高效算法——J 中途相遇法,求和

    ---恢复内容开始--- J - 中途相遇法 Time Limit:9000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Su ...

  7. 【UVALive】2965 Jurassic Remains(中途相遇法)

    题目 传送门:QWQ 分析 太喵了~~~~~ 还有中途相遇法这种东西的. 嗯 以后可以优化一些暴力 详情左转蓝书P58 (但可能我OI生涯中都遇不到正解是这个的题把...... 代码 #include ...

  8. uva1152 - 4 Values whose Sum is 0(枚举,中途相遇法)

    用中途相遇法的思想来解题.分别枚举两边,和直接暴力枚举四个数组比可以降低时间复杂度. 这里用到一个很实用的技巧: 求长度为n的有序数组a中的数k的个数num? num=upper_bound(a,a+ ...

  9. LA 2965 中途相遇法

    题目链接:https://vjudge.net/problem/UVALive-2965 题意: 有很多字符串(24),选出一些字符串,要求这些字符串的字母都是偶数次: 分析: 暴力2^24也很大了, ...

随机推荐

  1. Centos6安装mysql5.7最新版

    最近因为公司的服务器需要做基线和漏洞扫描,基线方面问题不大,按照报告上的加固建议,选一些权重高的问题处理一下就好了.但是漏洞扫描就比较坑了,扫出来了十几个高危和一百六十多个中危漏洞,不过还好漏洞基本上 ...

  2. day13 python生成器函数 推导式 生成器

    day13 python   一.生成器     生成器的本质就是迭代器     生成器的特点和迭代器一样. 取值方式和迭代器一样(__next__())     由生成器函数或生成器表达式来创建   ...

  3. SQL笔试题:下面是学生表(student)的结构说明

    SQL笔试题:下面是学生表(student)的结构说明 SQL笔试题:下面是学生表(student)的结构说明 字段名称 字段解释 字段类型 字段长度 约束 s_id 学号 字符 10 PK s_na ...

  4. 【串线篇】依赖注入DI与控制反转IOC

    DI&IOC 在spring框架中DI与IOC说的其实是一回事 一句话:本来我接受各种参数来构造一个对象,现在只接受一个参数——已经实例化的对象. 也就是说我对对象的『依赖』是注入进来的,而和 ...

  5. npm启动报错

    npm 启动报错  event.js 160 报错原因: 端口号被占用 解决方法: 1.重新定义一个端口号. 2.任务管理器关掉node进程,重新运行npm.

  6. List Comprehension ()(二)

    在list comprehension中加入if条件判断: >>> lines = [line.rstrip() for line in open('script2.py') if ...

  7. Django框架的学习

    目前 Django 1.6.x 以上版本已经完全兼容 Python 3.x. 1. 指定django版本的安装 pip install django =1.11

  8. Base64和3DES算法

    Base64加密算法 Base64是网络上最常见的用于传输8Bit字节代码的编码方式之一,可用于在HTTP环境下传递较长的标识信息.它的优点是算法效率高,编码出来的结果比较简短,同时也具有不可读性. ...

  9. AcWing 227. 小部件厂 (高斯消元)打卡

    题目:https://www.acwing.com/problem/content/description/229/ 题意:有很多个零件,每个零件的生产时间都在3-9天之间,现在只知道每个工人的生产部 ...

  10. 继续我们的学习。这次鸟哥讲的是LVM。。。磁盘管理 最后链接文章没有看

    LVM...让我理解就是一个将好多分区磁盘帮到一起的玩意,类似于烙大饼...然后再切 新建了一个虚拟机,然后又挂了一个5G的硬盘,然后分出了5块空间,挂载到了虚拟机上.这些步骤很简单 fdisk    ...