【题目链接】:http://hihocoder.com/problemset/problem/1516

【题意】

【题解】



状态压缩DP+bfs

这个过河问题能用bfs来搞.涨知识了;

首先;

16个人

容易想到用0..216−1来表示3处地方的状态;

即这一边的岸,船上,以及对岸;

对于岸上;

只需要这状态里面,能攻击人的人存在,且它攻击的对象也存在,且能管住这个攻击的人的人不在,则这个状态就是不符合要求的;

而对于船上;

则需要一个掌舵人,否则不行;

然后对于岸上的情况船上的情况也要满足;

还有就是船上的人数的限制了;

设f[i][0..1]分别表示某一边状态为i,然后船在某一边(用0和1表示)的最少渡河次数;

f[(1< < n)-1][0]=0;

然后每次枚举到对岸的人是哪些就好;

枚举的方法很巧妙;

for (int i = (1< < n)-1;i;i=(i-1)&now)

这个&运算保证了,只有当前存在的人才能过去;然后又能把所有情况都涉及到;

最后输出f[(1< < n)-1][1]

程序中can[i]判断i这状态能不能在船上

can2[i]判断i这个状态能不能在岸上



【Number Of WA】



0



【完整代码】

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. #define lson l,m,rt<<1
  4. #define rson m+1,r,rt<<1|1
  5. #define LL long long
  6. #define rep1(i,a,b) for (int i = a;i <= b;i++)
  7. #define rep2(i,a,b) for (int i = a;i >= b;i--)
  8. #define mp make_pair
  9. #define pb push_back
  10. #define fi first
  11. #define se second
  12. #define ms(x,y) memset(x,y,sizeof x)
  13. typedef pair<int,int> pii;
  14. typedef pair<LL,LL> pll;
  15. const int dx[9] = {0,1,-1,0,0,-1,-1,1,1};
  16. const int dy[9] = {0,0,0,-1,1,-1,1,-1,1};
  17. const double pi = acos(-1.0);
  18. const int N = 18;
  19. const int MAX = 7e4;
  20. int n,m,a,b,c,all;
  21. int son[N],fat[N],boa;
  22. bool can[MAX],can2[MAX];
  23. int f[MAX][2];
  24. queue <pii> dl;
  25. bool check(int statu)
  26. {
  27. if ((statu&boa)==0) return false;
  28. int cnt = 0;
  29. rep1(i,0,n-1)
  30. {
  31. if ((statu>>i)&1)
  32. {
  33. cnt++;
  34. if (((fat[i]&statu)==0) && (son[i]&statu))
  35. return false;
  36. }
  37. }
  38. if (cnt>m) return false;
  39. return true;
  40. }
  41. bool check2(int statu)
  42. {
  43. rep1(i,0,n-1)
  44. {
  45. if ((statu>>i)&1)
  46. {
  47. if (((fat[i]&statu)==0) && (son[i]&statu))
  48. return false;
  49. }
  50. }
  51. return true;
  52. }
  53. int main()
  54. {
  55. //freopen("F:\\rush.txt","r",stdin);
  56. ios::sync_with_stdio(false),cin.tie(0);//scanf,puts,printf not use
  57. cin >> n >> m;
  58. cin >> a >> b >> c;
  59. int x,y;
  60. rep1(i,1,a)
  61. {
  62. cin >> x >> y;
  63. son[x] |= (1<<y);
  64. }
  65. rep1(i,1,b)
  66. {
  67. cin >> x >> y;
  68. fat[y]|= (1<<x);
  69. }
  70. rep1(i,1,c)
  71. {
  72. cin >> x;
  73. boa |= (1<<x);
  74. }
  75. all = (1<<n)-1;
  76. rep2(i,all,0)
  77. {
  78. can[i] = check(i);
  79. can2[i] = check2(i);
  80. }
  81. if (!can2[all]) return cout <<-1<<endl,0;
  82. ms(f,255);
  83. f[all][0] = 0;
  84. dl.push(mp(all,0));
  85. while (!dl.empty())
  86. {
  87. int s = dl.front().fi,k = dl.front().se;dl.pop();
  88. for (int left = s;left;left=(left-1)&s)
  89. {
  90. if (can[left] && can2[all^s^left] && can2[s^left] && can2[all^s])
  91. {
  92. int status = all^s^left;
  93. if (f[status][k^1]==-1)
  94. {
  95. f[status][k^1] = f[s][k]+1;
  96. dl.push(mp(status,k^1));
  97. }
  98. }
  99. }
  100. }
  101. cout << f[all][1] << endl;
  102. return 0;
  103. }

【[Offer收割]编程练习赛15 C】过河问题的更多相关文章

  1. [Offer收割]编程练习赛15 B.分数调查[加权并查集]

    #1515 : 分数调查 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi的学校总共有N名学生,编号1-N.学校刚刚进行了一场全校的古诗文水平测验. 学校没有公布测 ...

  2. [Offer收割]编程练习赛15 A.偶像的条件[贪心]

    #1514 : 偶像的条件 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi的学校正面临着废校的大危机.面对学校的危机,小Hi同学们决定从ABC三个班中各挑出一名同 ...

  3. 【[Offer收割]编程练习赛15 B】分数调查

    [题目链接]:http://hihocoder.com/problemset/problem/1515 [题意] [题解] 带权并查集 relation[x]表示父亲节点比当前节点大多少; 对于输入的 ...

  4. 【[Offer收割]编程练习赛15 A】 偶像的条件

    [题目链接]:http://hihocoder.com/contest/offers15/problem/1 [题意] [题解] 把3个数组的元素全都合并在一个数组里面; (当然你要记录每个数字原本是 ...

  5. hihocoder [Offer收割]编程练习赛4

    描述 最近天气炎热,小Ho天天宅在家里叫外卖.他常吃的一家餐馆一共有N道菜品,价格分别是A1, A2, ... AN元.并且如果消费总计满X元,还能享受优惠.小Ho是一个不薅羊毛不舒服斯基的人,他希望 ...

  6. hihocoder [Offer收割]编程练习赛61

    [Offer收割]编程练习赛61 A:最小排列 给定一个长度为m的序列b[1..m],再给定一个n,求一个字典序最小的1~n的排列A,使得b是A的子序列. 贪心即可,b是A的子序列,把不在b中的元素, ...

  7. [Offer收割]编程练习赛46

    [Offer收割]编程练习赛46赛后题解 A.AEIOU 分析

  8. [Offer收割]编程练习赛23-freeloop

    A. H国的身份证号码I dfs裸题. 时间复杂度\(O(n^k)\). #include <bits/stdc++.h> #define FOR(i,a,b) for (int i=a; ...

  9. hihoCoder[Offer收割]编程练习赛1题目解析

    题目1 : 九宫 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描写叙述 小Hi近期在教邻居家的小朋友小学奥数.而近期正好讲述到了三阶幻方这个部分,三阶幻方指的是将1~9不反 ...

随机推荐

  1. windows下solr7.9+tomcat7环境搭建

    1.下载solr.tomcat(能够不用下载.由于solr有jetty支持) 2.solr部署到tomcat上    首先,把解压包下的solr-4.9.0\example\solr-webapp中的 ...

  2. Mybatis 框架文档 超具体笔记

    1      Mybatis入门 1.1    单独使用jdbc编程问题总结 1.1.1  jdbc程序 Public static void main(String[] args) { Connec ...

  3. JS中split使用方法和数组中元素的删除

    JS中split使用方法和数组中元素的删除 JS中split使用方法 <script language="javascript"> function spli(){ d ...

  4. oc48--多个对象内存管理练习

    // // main.m // 多个对象内存管理练习 // // ARC是Xcode帮我们生成内存释放的代码,MRC是需要我买自己写retain和release.想研究内存管理只能在MRC,管理对象就 ...

  5. sqlserver 创建维护计划失败(SQL Server: 14234 错误)自动备份数据库计划

    创建维护计划失败(SQL Server: 14234 错误) (2011-06-25 14:44:24) 转载▼ 标签: 杂谈 分类: MSSQL 错误信息:对于 JobStep ' testBak ...

  6. elasticsearch _field_stats 源码分析

    _field_stats 实现的功能:https://www.elastic.co/guide/en/elasticsearch/reference/5.6/search-field-stats.ht ...

  7. P1966 火柴排队(逆序对)

    P1966 火柴排队 题目描述 涵涵有两盒火柴,每盒装有 n 根火柴,每根火柴都有一个高度. 现在将每盒中的火柴各自排成一列, 同一列火柴的高度互不相同, 两列火柴之间的距离定义为: ∑(ai-bi) ...

  8. tp 3.1.3 动态切换模板问题

    if($this->isMobile()) { C('DEFAULT_THEME', 'mobile'); // 这里定义手机模板目录 C('TMPL_CACHE_PREFIX', 'm_'); ...

  9. C - Domino piling

    Problem description You are given a rectangular board of M × N squares. Also you are given an unlimi ...

  10. ReferenceEquals()、static Equals() 、instance Equals() 与 operator==之间的联系与区别

    当你创建一个用户自定义类型(类或结构)时,你需要给你的类型定义相等操作.C#中提供了几个不同的函数来验证两个对象是否满足“相等”的含义.public static bool ReferenceEqua ...