[HNOI 2007]神奇游乐园

#include <bits/stdc++.h>
#define maxn 110
using namespace std;
typedef long long ll;
int n, m;
int a[maxn][maxn];
ll ans = -1ll << 60;
#define M 2000010
#define mod 997struct Hashmap{ll st[M];int h[1000], size, nxt[M];ll f[M];void clear(){memset(h, 0, sizeof h); size = 0;}void push(ll hash_, ll val){int tmp = hash_ % mod;for(int i = h[tmp]; i; i = nxt[i]){if(st[i] == hash_){f[i] = max(f[i], val);return;}}int now = ++ size;f[now] = val;st[now] = hash_;nxt[now] = h[tmp];h[tmp] = now;}
}dp[2];int cur, code[20], ch[20];void Decode(ll st){for(int i = m; i >= 0; i --)code[i] = st & 7, st >>= 3;
}ll Encode(){ll ret = 0;memset(ch, -1, sizeof ch);ch[0] = 0; int cnt = 0;for(int i = 0; i <= m; i ++){if(ch[code[i]] == -1)ch[code[i]] = ++ cnt;code[i] = ch[code[i]];ret = ret << 3 | code[i];}return ret;
}void Shift(){for(int i = m; i >= 1; i --)code[i] = code[i-1];code[0] = 0;
}inline void Change(int u, int v){for(int i = 0; i <= m; i ++)if(code[i] == v)code[i] = u;
}void DP(int i, int j){dp[cur^1].clear();for(int k = 1; k <= dp[cur].size; k ++){Decode(dp[cur].st[k]);if(j == 1){if(code[m])continue;Shift();}int Left = code[j-1], Up = code[j];if(Left && Up){code[j] = code[j-1] = 0;if(Left == Up){ll ENCODE = Encode();if(ENCODE == 0)ans = max(ans, dp[cur].f[k] + a[i][j]);}else{Change(Left, Up);dp[cur^1].push(Encode(), dp[cur].f[k] + a[i][j]);}}else if(Left || Up){int tmp = Left ? Left : Up;code[j-1] = 0, code[j] = tmp;dp[cur^1].push(Encode(), dp[cur].f[k] + a[i][j]);code[j] = 0, code[j-1] = tmp;dp[cur^1].push(Encode(), dp[cur].f[k] + a[i][j]);}else{dp[cur^1].push(Encode(), dp[cur].f[k]);code[j] = code[j-1] = 8;dp[cur^1].push(Encode(), dp[cur].f[k] + a[i][j]);}}cur ^= 1;
}int main(){
#ifndef ONLINE_JUDGEfreopen("park.in","r",stdin);freopen("park.out","w",stdout);
#endifscanf("%d%d", &n, &m);for(int i = 1; i <= n; i ++)for(int j = 1; j <= m; j ++)scanf("%d", &a[i][j]);dp[cur].clear();dp[cur].push(0, 0);for(int i = 1; i <= n; i ++)for(int j = 1; j <= m; j ++)DP(i, j);printf("%lld\n", ans);return 0;
}

粘了一个模板上来=-=

基于连通性的动态规划,最小表示法很好用。

我们可以用一个压缩的数字表示一个连通情况,比如DP生成树,概率,棋盘上格子的情况,等等等

只要和连通性有关而且n很小时就可以用啦QAQ。

又忘了模板了QAQ

就是如果左边和上面是一个连通分量即Left == Up时,我们要合并连通分量,所以此时已经出现了一个圈了,这道题不能有多个圈,所以最后不放进去

code[j] = code[j-1] = 0.

[BZOJ 3753]Wall

扩展一下方格变成一个回路问题,然后射线法判断格子是否内部。

出现的问题是当left == up时,code[j] = code[j-1] = 0,然后再改所有的标号

当必须只能有一个回路的时候,Encode()一定要等于0.

#include <bits/stdc++.h>
#define maxn 20
using namespace std;
typedef long long ll;
int n, m;int need[maxn][maxn], a[maxn][maxn];int cur = 0, Cnt, cnt;const int md = 997;struct Hashmap{#define M 2000010ll st[M];int f[M], h[1000], nxt[M], size;void init(){memset(h, 0, sizeof h);size = 0;}void push(ll hs, int val){int tmp = hs % md;for(int i = h[tmp]; i; i = nxt[i]){if(st[i] == hs){f[i] = max(f[i], val);return;}}int now = ++ size;f[now] = val;nxt[now] = h[tmp];st[now] = hs;h[tmp] = now;}
}dp[2];int code[maxn], ch[maxn];void Decode(ll st){for(int i = m; i >= 0; i --)code[i] = st & 7, st >>= 3;
}ll Encode(){ll ret = 0;memset(ch, -1, sizeof ch);ch[0] = 0; int cnt = 0;for(int i = 0; i <= m; i ++){if(ch[code[i]] == -1)ch[code[i]] = ++ cnt;code[i] = ch[code[i]];ret <<= 3;ret |= code[i];}return ret;
}void Shift(){for(int i = m; i; i --)code[i] = code[i-1];code[0] = 0;
}bool Judge(int cnt, int i, int j){if(cnt && need[i][j] == 1)return false;if(!cnt && need[i][j] == 2)return false;return true;
}int ans = -0x7fffffff;void Trans(int i, int j){dp[cur^1].init();for(int k = 1; k <= dp[cur].size; k ++){Decode(dp[cur].st[k]);if(j == 1){if(code[m])continue;Shift();}int lf = code[j-1], up = code[j], sta = 0;for(int p = 0; p < j-1; p ++)sta ^= (code[p] != 0);if(lf && up){code[j] = code[j-1] = 0;if(lf == up){if(Encode() == 0 && cnt == Cnt)//here!ans = max(ans, dp[cur].f[k]);}else{if(Judge(sta, i, j)){for(int p = 0; p <= m; p ++)if(code[p] == up)code[p] = lf;dp[cur^1].push(Encode(), dp[cur].f[k] + sta * a[i][j]);}}}else if(lf || up){int tmp = lf ? lf : up;if(Judge(sta, i, j)){code[j-1] = 0, code[j] = tmp;dp[cur^1].push(Encode(), dp[cur].f[k] + sta * a[i][j]);}sta ^= 1;if(Judge(sta, i, j)){code[j] = 0, code[j-1] = tmp;dp[cur^1].push(Encode(), dp[cur].f[k] + sta * a[i][j]);}}else{if(Judge(sta, i, j))dp[cur^1].push(Encode(), dp[cur].f[k] + sta * a[i][j]);sta ^= 1;if(Judge(sta, i, j)){code[j] = code[j-1] = 15;dp[cur^1].push(Encode(), dp[cur].f[k] + sta * a[i][j]);}}}if(need[i][j] == 2)cnt ++;cur ^= 1;
}int main(){scanf("%d%d", &n, &m);for(int i = 1; i <= n; i ++)for(int j = 1; j <= m; j ++)scanf("%d", &a[i][j]);n ++, m ++;dp[cur].init();dp[cur].push(0, 0);for(int i = 1; i <= n; i ++)for(int j = 1; j <= m; j ++)Trans(i, j);printf("%d\n", ans);for(int i = 1; i < n; i ++)for(int j = 1; j < m; j ++)scanf("%d", &need[i][j]), Cnt += need[i][j] == 2;ans = -0x7fffffff;dp[cur].init();dp[cur].push(0, 0);for(int i = 1; i <= n; i ++)for(int j = 1; j <= m; j ++)Trans(i, j);if(ans < -0x7ffffff)printf("Can not establish GFW.");else printf("%d\n", ans);return 0;
}

转载于:https://www.cnblogs.com/Candyouth/p/5392609.html

[插头DP自我总结]相关推荐

  1. bzoj1814 Ural 1519 Formula 1(插头dp模板题)

    1814: Ural 1519 Formula 1 Time Limit: 1 Sec  Memory Limit: 64 MB Submit: 924  Solved: 351 [Submit][S ...

  2. [入门向选讲] 插头DP:从零概念到入门 (例题:HDU1693 COGS1283 BZOJ2310 BZOJ2331)

    转载请注明原文地址:http://www.cnblogs.com/LadyLex/p/7326874.html 最近搞了一下插头DP的基础知识--这真的是一种很锻炼人的题型-- 每一道题的状态都不一样 ...

  3. HDU4084 插头dp

    题意:给定一个图,0是不能放的,然后现在有1X1和1X2方块,最后铺满该图,使得1X1使用次数在C到D之间,1X2次数随便,问有几种放法 思路:插头DP或轮廓线,多加一维DP讨论就可以 注意插头DP状 ...

  4. POJ3133(插头dp)

    传送门:http://poj.org/problem?id=3133 Manhattan Wiring Time Limit: 5000MS   Memory Limit: 65536K       ...

  5. P3272 [SCOI2011]地板(插头DP)

    [题面链接] https://www.luogu.org/problemnew/show/P3272 [题目描述] 有一个矩阵,有些点必须放,有些点不能放,用一些L型的图形放满,求方案数 [题解] ( ...

  6. POJ 3133 Manhattan Wiring (插头DP)

    Manhattan Wiring Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 1110   Accepted: 634 D ...

  7. URAL1519 Formula 1 —— 插头DP

    题目链接:https://vjudge.net/problem/URAL-1519 1519. Formula 1 Time limit: 1.0 second Memory limit: 64 MB ...

  8. [集训队作业2018]小Z的礼物(min-max容斥,插头dp)

    传送门 这种求 "取到所有物品的期望时间" 的题一般都用 min−maxmin-maxmin−max容斥 解决: 设t(i,j)t(i,j)t(i,j)为取到格子(i,j)(i,j ...

  9. 【BZOJ1814】Ural 1519 Formula 1 插头DP

    [BZOJ1814]Ural 1519 Formula 1 题意:一个 m * n 的棋盘,有的格子存在障碍,求经过所有非障碍格子的哈密顿回路个数.(n,m<=12) 题解:插头DP板子题,刷板 ...

最新文章

  1. WebMatrix 3发布了!
  2. javascript自动跳转
  3. VS2008如何自动添加消息映射
  4. pandas dataframe对多列同时排序
  5. php input 只接收文件内容,一文搞懂$_POST和file_get_contents(“php://input”)的区别
  6. livedata mvvm_Android MVVM LiveData数据绑定
  7. jq 获取当时时间的到秒_js(jQuery)获取时间的方法及常用时间类
  8. Spss的基本方法使用步骤
  9. FishC笔记—01 讲:我和 Python 第一次亲密接触
  10. IGBT工作原理及作用
  11. 新睿云告诉您主流操作:分布式操作系统、批处理操作系统、分时操作系统优缺点分析!
  12. cleaned_data
  13. 使用SendCloud API来制作发送邮件的插件
  14. keil5的安装详解(看完必会,不会你打我)
  15. 神马!看电子书,会让记忆力衰退!
  16. 干货:esp32彩屏自制太空人主题透明手表!
  17. 知乎盐选会员-share1223会员商城
  18. 中国医科大学2021年12月《中医护理学基础》作业考核试题
  19. Gmap.net搜集
  20. React Native之样式

热门文章

  1. linux网卡pci信息,在进行CGKlinux系统网络配置时,使用()命令可以查询出网卡的PCI编号与设备名的对应关系。...
  2. dataframe修改数据_利用Python进行数据分析(语法篇)
  3. pdf在线翻译_如何将英文的PDF文档翻译成中文简体?
  4. 【算法】剑指 Offer 63. 股票的最大利润
  5. 60-100-026-使用-MySQL 行锁
  6. 【kafka】Kafka 2.0 ConsumerGroupCommand新功能
  7. 【MySQL】MySQL监控工具 mysql-monitor
  8. 【Hadoop】Bad connect ack with firstBadLink as ×.×.×.×:50010
  9. 10-Bootstrap Checksedit
  10. Java web 中的 三层架构