原题链接

题目大意

\(n\times n\)的带权方阵,选一个权值最大的连通块

Solution

一眼连通性DP,然后就没了

转移很好想的啦,简单讨论一下就行了

有一个坑点,就是不能一个格子都不选,特判一下

注释还算详细QwQ

  1. #include <algorithm>
  2. #include <iostream>
  3. #include <cstdlib>
  4. #include <cstring>
  5. #include <cstdio>
  6. #include <string>
  7. #include <vector>
  8. #include <cmath>
  9. #include <ctime>
  10. #include <queue>
  11. #include <map>
  12. #include <set>
  13. using namespace std;
  14. #define ull unsigned long long
  15. #define pii pair<int, int>
  16. #define uint unsigned int
  17. #define mii map<int, int>
  18. #define lbd lower_bound
  19. #define ubd upper_bound
  20. #define INF 0x3f3f3f3f
  21. #define IINF 0x3f3f3f3f3f3f3f3fLL
  22. #define DEF 0x8f8f8f8f
  23. #define DDEF 0x8f8f8f8f8f8f8f8fLL
  24. #define vi vector<int>
  25. #define ll long long
  26. #define mp make_pair
  27. #define pb push_back
  28. #define re register
  29. #define il inline
  30. #define N 10
  31. #define MOD 114511
  32. int n;
  33. int val[N+5][N+5], ans = DEF, bin[N+5];
  34. namespace HashTable { //哈希表所需
  35. int lst, cur, head[MOD+5], nxt[MOD+5], tot[2];
  36. int f[2][MOD+5], a[2][MOD+5];
  37. void insert(int x, int v) { // 把x状态的最优值与v取max
  38. int x0 = x%MOD, i;
  39. for(i = head[x0]; i; i = nxt[i]) if(a[cur][i] == x) break;
  40. if(!i) nxt[++tot[cur]] = head[x0], f[cur][tot[cur]] = DEF, a[cur][tot[cur]] = x, head[x0] = i = tot[cur];
  41. f[cur][i] = max(f[cur][i], v);
  42. }
  43. }
  44. using namespace HashTable;
  45. // 最多有5(9/2向上取整)个联通块
  46. // 采用8进制压缩
  47. int decode(int s0, int v) { // 最小表示所需
  48. static int tf[8];
  49. int cnt = 0, s = 0;
  50. memset(tf, 0, sizeof tf);
  51. for(int i = 0; i < n; ++i) {
  52. int x = (s0>>(3*i))%8;
  53. if(!x) continue;
  54. if(!tf[x]) tf[x] = ++cnt;
  55. s += tf[x]*bin[i];
  56. }
  57. if(cnt == 1) ans = max(ans, v); // 顺便更新全局最优解
  58. return s;
  59. }
  60. int main() {
  61. scanf("%d", &n);
  62. bin[0] = 1;
  63. for(int i = 1; i <= n; ++i) bin[i] = bin[i-1]<<3;
  64. for(int i = 1; i <= n; ++i)
  65. for(int j = 1; j <= n; ++j) scanf("%d", &val[i][j]), ans = max(ans, val[i][j]);
  66. insert(0, 0); // 初始化
  67. for(int i = 1; i <= n; ++i) {
  68. for(int j = 1; j <= n; ++j) {
  69. lst = cur, cur ^= 1, tot[cur] = 0;
  70. memset(head, 0, sizeof head);
  71. for(int k = 1; k <= tot[lst]; ++k) {
  72. int s = a[lst][k], v = f[lst][k], p1, p2 = (s>>(3*(j-1)))%8;
  73. if(j == 1) p1 = 0;
  74. else p1 = (s>>(3*(j-2)))%8;
  75. if(!p1 && !p2) { // 左和上都没有选
  76. insert(decode(s, v), v); // 当前不选
  77. insert(decode(s+7*bin[j-1], v+val[i][j]), v+val[i][j]); // 当前选
  78. }
  79. else if(p1 && !p2) { // 只有左选了
  80. insert(decode(s, v), v); // 当前不选
  81. insert(decode(s+p1*bin[j-1], v+val[i][j]), v+val[i][j]); // 当前选
  82. }
  83. else if(!p1 && p2) { // 只有上选了
  84. int cnt = 0;
  85. for(int p = 0; p < n; ++p) if((s>>(3*p))%8 == p2) cnt++; // 只要这个连通块还有另一处与轮廓线相交就可以不选当前的
  86. if(cnt >= 2) insert(decode(s-p2*bin[j-1], v), v); // 当前不选
  87. insert(decode(s, v+val[i][j]), v+val[i][j]); // 当前选
  88. }
  89. else { // 左和上都选了
  90. int cnt = 0;
  91. for(int p = 0; p < n; ++p) if((s>>(3*p))%8 == p2) cnt++; // 与上一种情况同理
  92. if(cnt >= 2) insert(decode(s-p2*bin[j-1], v), v); // 当前不选
  93. if(p1 != p2) for(int p = 0; p < n; ++p) if((s>>(3*p))%8 == p2) s += p1*bin[p]-p2*bin[p]; // 合并两个连通块
  94. insert(decode(s, v+val[i][j]), v+val[i][j]); // 当前选
  95. }
  96. }
  97. }
  98. }
  99. printf("%d\n", ans);
  100. return 0;
  101. }

[JLOI2009]神秘的生物——轮廓线DP的更多相关文章

  1. Luogu P3886 [JLOI2009]神秘的生物 最小表示法,轮廓线DP,插头DP,动态规划

    亲手写掉的第一道最小表示法!哈哈哈太开心啦~ 不同于以往的几个插头\(dp\),这个题目的轮廓线是周围的一圈\(n\)个格子.而其所谓"插头"也变成了相邻格子的所属连通分量编号,并 ...

  2. [JLOI2009]神秘的生物

    题目链接 题目大意 给定一个\(n*n\)的矩阵,从其中选取恰好一个连通块,使选取的格子所对应的权值和最大. \(n\leq 9\) 解题思路 由于\(n\)特别小,考虑插头dp. 和一般的插头dp不 ...

  3. 轮廓线DP POJ3254 && BZOJ 1087

    补了一发轮廓线DP,发现完全没有必要从右往左设置状态,自然一点: 5 6 7 8 9 1 2 3 4 如此设置轮廓线标号,转移的时候直接把当前j位改成0或者1就行了.注意多记录些信息对简化代码是很有帮 ...

  4. HDU4804 Campus Design 轮廓线dp

    跟上面那篇轮廓线dp是一样的,但是多了两个条件,一个是在原图上可能有些点是不能放的(即障碍),所以转移的时候要多一个判断color[i][j]是不是等于1什么的,另外一个是我们可以有多的1*1的骨牌, ...

  5. POJ2411 Mondriaan's Dream 轮廓线dp

    第一道轮廓线dp,因为不会轮廓线dp我们在南京区域赛的时候没有拿到银,可见知识点的欠缺是我薄弱的环节. 题目就是要你用1*2的多米诺骨排填充一个大小n*m(n,m<=11)的棋盘,问填满它有多少 ...

  6. UVA - 11270 轮廓线DP

    其实这题还能用状压DP解决,可是时间达到2000ms只能过掉POJ2411.状压DP解法详见状压DP解POJ2411 贴上POJ2411AC代码 : 2000ms 时间复杂度h*w*(2^w)*(2^ ...

  7. [UOJ422][集训队作业2018]小Z的礼物——轮廓线DP+min-max容斥

    题目链接: [集训队作业2018]小Z的礼物 题目要求的就是最后一个喜欢的物品的期望得到时间. 根据$min-max$容斥可以知道$E(max(S))=\sum\limits_{T\subseteq ...

  8. 【UOJ#422】【集训队作业2018】小Z的礼物(min-max容斥,轮廓线dp)

    [UOJ#422][集训队作业2018]小Z的礼物(min-max容斥,轮廓线dp) 题面 UOJ 题解 毒瘤xzy,怎么能搬这种题当做WC模拟题QwQ 一开始开错题了,根本就不会做. 后来发现是每次 ...

  9. BZOJ.4572.[SCOI2016]围棋(轮廓线DP)

    BZOJ 洛谷 \(Description\) 给定\(n,m,c\).\(Q\)次询问,每次询问给定\(2*c\)的模板串,求它在多少个\(n*m\)的棋盘中出现过.棋盘的每个格子有三种状态. \( ...

随机推荐

  1. redis 获取方式和安装(windows)

    Windows redis :https://github.com/MSOpenTech/redis/releases Linux redis :https://github.com/phpredis ...

  2. Sightseeing tour 【混合图欧拉回路】

    题目链接:http://poj.org/problem?id=1637 Sightseeing tour Time Limit: 1000MS   Memory Limit: 10000K Total ...

  3. [bzoj1151][CTSC2007]动物园zoo_状压dp

    动物园zoo 题目大意:https://www.lydsy.com/JudgeOnline/problem.php?id=1151 题解: 我们发现每个点只会往右延伸$5$个,这个数非常小. 再加上每 ...

  4. Closest Common Ancestors (Lca,tarjan)

    午时刷题,难甚,遂小憩于桌上,惊醒,于梦中有所得,虽大声曰:吾已得tarjan之奥秘! 关于tarjan算法,其实就是一个递归加并查集的应用. 大致代码: #include<bits/stdc+ ...

  5. S03_CH01_AXI_DMA_LOOP 环路测试

    S03_CH01_AXI_DMA_LOOP 环路测试 1.1概述 本课程是本季课程里面最简单,也是后面DMA课程的基础,读者务必认真先阅读和学习. 本课程的设计原理分析. 本课程是设计一个最基本的DM ...

  6. Java装饰者模式(思维导图)

    图1 装饰者模式[点击查看图片] 1,一个简单的以人为主体的装饰者模式 被装饰者 public interface Human {//被装饰者 public void wearClothes(); p ...

  7. Nopcommerce 项目添加插件

    插件是用来扩展nopCommerce功能的.nopCommerce拥有多种类型的插件.例如:支付方式(PayPal),税务机构,送货方式计算方法(UPS, USP, FedEx),小部件(如“在线聊天 ...

  8. 无法删除登录名 '***',因为该用户当前正处于登录状态。 (Microsoft SQL Server,错误: 15434)

    问题描述: 当删除数据库用户时,有时会得到这样的提示: 无法删除登录名 '***',因为该用户当前正处于登录状态. (Microsoft SQL Server,错误: 15434) 解决办法: 1.首 ...

  9. java代码实现mock数据

    废话不多说,直接上代码. /** * 发get请求,获取文本 * * @param getUrl * @return 网页context */ public static String sendGet ...

  10. struts-2.5.14.1中jar包引入