[插头DP自我总结]
[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自我总结]相关推荐
- 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 ...
- [入门向选讲] 插头DP:从零概念到入门 (例题:HDU1693 COGS1283 BZOJ2310 BZOJ2331)
转载请注明原文地址:http://www.cnblogs.com/LadyLex/p/7326874.html 最近搞了一下插头DP的基础知识--这真的是一种很锻炼人的题型-- 每一道题的状态都不一样 ...
- HDU4084 插头dp
题意:给定一个图,0是不能放的,然后现在有1X1和1X2方块,最后铺满该图,使得1X1使用次数在C到D之间,1X2次数随便,问有几种放法 思路:插头DP或轮廓线,多加一维DP讨论就可以 注意插头DP状 ...
- POJ3133(插头dp)
传送门:http://poj.org/problem?id=3133 Manhattan Wiring Time Limit: 5000MS Memory Limit: 65536K ...
- P3272 [SCOI2011]地板(插头DP)
[题面链接] https://www.luogu.org/problemnew/show/P3272 [题目描述] 有一个矩阵,有些点必须放,有些点不能放,用一些L型的图形放满,求方案数 [题解] ( ...
- POJ 3133 Manhattan Wiring (插头DP)
Manhattan Wiring Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 1110 Accepted: 634 D ...
- URAL1519 Formula 1 —— 插头DP
题目链接:https://vjudge.net/problem/URAL-1519 1519. Formula 1 Time limit: 1.0 second Memory limit: 64 MB ...
- [集训队作业2018]小Z的礼物(min-max容斥,插头dp)
传送门 这种求 "取到所有物品的期望时间" 的题一般都用 min−maxmin-maxmin−max容斥 解决: 设t(i,j)t(i,j)t(i,j)为取到格子(i,j)(i,j ...
- 【BZOJ1814】Ural 1519 Formula 1 插头DP
[BZOJ1814]Ural 1519 Formula 1 题意:一个 m * n 的棋盘,有的格子存在障碍,求经过所有非障碍格子的哈密顿回路个数.(n,m<=12) 题解:插头DP板子题,刷板 ...
最新文章
- WebMatrix 3发布了!
- javascript自动跳转
- VS2008如何自动添加消息映射
- pandas dataframe对多列同时排序
- php input 只接收文件内容,一文搞懂$_POST和file_get_contents(“php://input”)的区别
- livedata mvvm_Android MVVM LiveData数据绑定
- jq 获取当时时间的到秒_js(jQuery)获取时间的方法及常用时间类
- Spss的基本方法使用步骤
- FishC笔记—01 讲:我和 Python 第一次亲密接触
- IGBT工作原理及作用
- 新睿云告诉您主流操作:分布式操作系统、批处理操作系统、分时操作系统优缺点分析!
- cleaned_data
- 使用SendCloud API来制作发送邮件的插件
- keil5的安装详解(看完必会,不会你打我)
- 神马!看电子书,会让记忆力衰退!
- 干货:esp32彩屏自制太空人主题透明手表!
- 知乎盐选会员-share1223会员商城
- 中国医科大学2021年12月《中医护理学基础》作业考核试题
- Gmap.net搜集
- React Native之样式
热门文章
- linux网卡pci信息,在进行CGKlinux系统网络配置时,使用()命令可以查询出网卡的PCI编号与设备名的对应关系。...
- dataframe修改数据_利用Python进行数据分析(语法篇)
- pdf在线翻译_如何将英文的PDF文档翻译成中文简体?
- 【算法】剑指 Offer 63. 股票的最大利润
- 60-100-026-使用-MySQL 行锁
- 【kafka】Kafka 2.0 ConsumerGroupCommand新功能
- 【MySQL】MySQL监控工具 mysql-monitor
- 【Hadoop】Bad connect ack with firstBadLink as ×.×.×.×:50010
- 10-Bootstrap Checksedit
- Java web 中的 三层架构