原题链接

题目大意

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

Solution

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

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

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

注释还算详细QwQ

#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <string>
#include <vector>
#include <cmath>
#include <ctime>
#include <queue>
#include <map>
#include <set> using namespace std; #define ull unsigned long long
#define pii pair<int, int>
#define uint unsigned int
#define mii map<int, int>
#define lbd lower_bound
#define ubd upper_bound
#define INF 0x3f3f3f3f
#define IINF 0x3f3f3f3f3f3f3f3fLL
#define DEF 0x8f8f8f8f
#define DDEF 0x8f8f8f8f8f8f8f8fLL
#define vi vector<int>
#define ll long long
#define mp make_pair
#define pb push_back
#define re register
#define il inline #define N 10
#define MOD 114511 int n;
int val[N+5][N+5], ans = DEF, bin[N+5]; namespace HashTable { //哈希表所需
int lst, cur, head[MOD+5], nxt[MOD+5], tot[2];
int f[2][MOD+5], a[2][MOD+5];
void insert(int x, int v) { // 把x状态的最优值与v取max
int x0 = x%MOD, i;
for(i = head[x0]; i; i = nxt[i]) if(a[cur][i] == x) break;
if(!i) nxt[++tot[cur]] = head[x0], f[cur][tot[cur]] = DEF, a[cur][tot[cur]] = x, head[x0] = i = tot[cur];
f[cur][i] = max(f[cur][i], v);
}
} using namespace HashTable; // 最多有5(9/2向上取整)个联通块
// 采用8进制压缩 int decode(int s0, int v) { // 最小表示所需
static int tf[8];
int cnt = 0, s = 0;
memset(tf, 0, sizeof tf);
for(int i = 0; i < n; ++i) {
int x = (s0>>(3*i))%8;
if(!x) continue;
if(!tf[x]) tf[x] = ++cnt;
s += tf[x]*bin[i];
}
if(cnt == 1) ans = max(ans, v); // 顺便更新全局最优解
return s;
} int main() {
scanf("%d", &n);
bin[0] = 1;
for(int i = 1; i <= n; ++i) bin[i] = bin[i-1]<<3;
for(int i = 1; i <= n; ++i)
for(int j = 1; j <= n; ++j) scanf("%d", &val[i][j]), ans = max(ans, val[i][j]);
insert(0, 0); // 初始化
for(int i = 1; i <= n; ++i) {
for(int j = 1; j <= n; ++j) {
lst = cur, cur ^= 1, tot[cur] = 0;
memset(head, 0, sizeof head);
for(int k = 1; k <= tot[lst]; ++k) {
int s = a[lst][k], v = f[lst][k], p1, p2 = (s>>(3*(j-1)))%8;
if(j == 1) p1 = 0;
else p1 = (s>>(3*(j-2)))%8;
if(!p1 && !p2) { // 左和上都没有选
insert(decode(s, v), v); // 当前不选
insert(decode(s+7*bin[j-1], v+val[i][j]), v+val[i][j]); // 当前选
}
else if(p1 && !p2) { // 只有左选了
insert(decode(s, v), v); // 当前不选
insert(decode(s+p1*bin[j-1], v+val[i][j]), v+val[i][j]); // 当前选
}
else if(!p1 && p2) { // 只有上选了
int cnt = 0;
for(int p = 0; p < n; ++p) if((s>>(3*p))%8 == p2) cnt++; // 只要这个连通块还有另一处与轮廓线相交就可以不选当前的
if(cnt >= 2) insert(decode(s-p2*bin[j-1], v), v); // 当前不选
insert(decode(s, v+val[i][j]), v+val[i][j]); // 当前选
}
else { // 左和上都选了
int cnt = 0;
for(int p = 0; p < n; ++p) if((s>>(3*p))%8 == p2) cnt++; // 与上一种情况同理
if(cnt >= 2) insert(decode(s-p2*bin[j-1], v), v); // 当前不选
if(p1 != p2) for(int p = 0; p < n; ++p) if((s>>(3*p))%8 == p2) s += p1*bin[p]-p2*bin[p]; // 合并两个连通块
insert(decode(s, v+val[i][j]), v+val[i][j]); // 当前选
}
}
}
}
printf("%d\n", ans);
return 0;
}

[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. 最新 搜狐java校招面经 (含整理过的面试题大全)

    从6月到10月,经过4个月努力和坚持,自己有幸拿到了网易雷火.京东.去哪儿.搜狐等10家互联网公司的校招Offer,因为某些自身原因最终选择了搜狐.6.7月主要是做系统复习.项目复盘.LeetCode ...

  2. linux下jenkins的安装

    构建伟大,无所不能 Jenkins是开源CI&CD软件领导者, 提供超过1000个插件来支持构建.部署.自动化, 满足任何项目的需要. 参考博客:https://www.cnblogs.com ...

  3. web漏洞

    *参考网站 https://cxsecurity.com/ https://www.exploit-db.com/ https://www.seebug.org/ http://www.securit ...

  4. Minimizing Difference 【思维】

    题目链接: https://vjudge.net/contest/336389#problem/B 题目大意: 给出一个长度为n的数列以及操作次数k.k的范围为1e14.每次操作都可以选择给任意一个数 ...

  5. 局部内部类的final问题

    局部内部类,如果希望访问所在方法的局部变量,那么这个局部变量就必须是final的(或者只赋值一次) 从Java8开始,只要局部变量事实不变那么final关键字可以省略 为什么需要保证变量为final, ...

  6. poj1696(极角排序,贪心)

    ---恢复内容开始--- 题目链接:https://vjudge.net/problem/POJ-1696 题意:有n个点,规定起点,每次只能向左走,不能与之前的路径交叉,求最多能经过几个点. 思路: ...

  7. #【Python】【demo实验34】【练习实例】【设置文本的颜色】

    原题: 文本颜色设置. 我的代码 #!/usr/bin/python # encoding=utf-8 # -*- coding: UTF-8 -*- # 文本颜色设置. class bcolors: ...

  8. Nginx04---编译安装

    原文:https://www.cnblogs.com/zhang-shijie/p/5294162.html 一:基介绍 官网地址www.nginx.org,nginx是由1994年毕业于俄罗斯国立莫 ...

  9. Spark Scala当中reduce的用法和例子

    [学习笔记] reduce将RDD中元素前两个传给输入函数,产生一个新的return值,将新产生的return值与RDD中下一个元素(即第三个元素)组成两个元素,再被传给输入函数,这样递归运作,直到最 ...

  10. Caesar's Legions(CodeForces-118D) 【DP】

    题目链接:https://vjudge.net/problem/CodeForces-118D 题意:有n1名步兵和n2名骑兵,现在要将他们排成一列,并且最多连续k1名步兵站在一起,最多连续k2名骑兵 ...