【10.26校内测试】【状压?DP】【最小生成树?搜索?】

Solution
据说正解DP30行???
然后写了100行的状压DP??
疯狂特判,一算极限时间复杂度过不了aaa!!
然而还是过了....QAQ
所以我定的状态是待转移的位置的前三位,用6位二进制位表示,每2位表示一个位置的状态。然后特判转移就可以了QAQ
Code
#include<bits/stdc++.h>
#define LL long long
#define mod 1000000007
#define RG register
using namespace std; char fi[];
int a[];
LL dp[][];
int len; int change(char x) {
if(x == '?') return ;
if(x == '*') return ;
if(x == '') return ;
if(x == '') return ;
if(x == '') return ;
} bool check(int s, int i) {
int pre = s & ( << );
int s1 = s >> , s2 = (s ^ pre) >> , s3 = s & ;
if(~a[i] && a[i] != && s3 != a[i]) return ;
if(i - > && a[i - ] != && s2 != a[i - ]) return ;
if(i - > && a[i - ] != && s1 != a[i - ]) return ;
if(i == len) {
if(s3 == && s2 != ) return ;
if(s3 == ) return ;
if(s3 == && s2 == ) return ;
}
if(i == ) {
if(s1 || s2) return ;
if(s3 == ) return ;
return ;
} else if(i == ) {
if(s1) return ;
if(s2 == && s3 == ) return ;
if(s2 == && s3 != ) return ;
if(s2 == ) return ;
if(s2 == && s3 == ) return ;
if(s3 == && s2 != ) return ;
return ;
}
if(s1 == && s2 == ) return ;
if(s1 == && s2 == ) return ;
if(s1 == && s2 != ) return ;
if(s1 == && s2 == ) return ;
if(s2 == && (s1 == || s3 == )) return ;
if(s2 == && s1 == && s3 == ) return ;
if(s2 == && (s1 != && s3 != )) return ;
if(s2 == && (s1 != || s3 != )) return ;
if(s2 == && (s1 == || s3 == )) return ;
if(s3 == && s2 == ) return ;
if(s3 == && s2 == ) return ;
if(s3 == && s2 != ) return ;
if(s3 == && s2 == ) return ;
return ;
} int main() {
freopen("mine.in", "r", stdin);
freopen("mine.out", "w", stdout);
scanf("%s", fi + );
len = strlen(fi + );
if(len == ) {
if(fi[] == '' || fi[] == '?') puts("");
else puts("");
return ;
}
memset(a, -, sizeof(a));
for(int i = ; i <= len; i ++)
a[i] = change(fi[i]);
int now = ;
if(a[] != ) {
dp[now][a[]] = ;
} else dp[now][] = dp[now][] = dp[now][] = dp[now][] = ;
for(RG int i = ; i <= len; i ++) {
now ^= ;
memset(dp[now], , sizeof(dp[now]));
for(RG int s = ; s < ( << ); s ++) {
int pre = s & ( << );
if(!check(s, i - )) continue;
if(a[i] != ) {
int ss = (s ^ pre) << | a[i];
if(!check(ss, i)) continue;
dp[now][ss] = (dp[now ^ ][s] + dp[now][ss]) % mod;
} else {
for(RG int k = ; k <= ; k ++) {
int ss = (s ^ pre) << | k;
if(!check(ss, i)) continue;
dp[now][ss] = (dp[now ^ ][s] + dp[now][ss]) % mod;
}
}
}
}
LL ans = ;
for(int s = ; s < ( << ); s ++)
if(check(s, len)) ans = (ans + dp[now][s]) % mod;
printf("%lld", ans);
return ;
}


Solution
完全把题意理解错了QAQ
以为从每一个点开始一直就只能向上下左右四个方向走了QAQ
结果一波暴力还得了20pts??
正解不懂QAQ然而$zyl$dalao爆搜轻松过!
其实也不是很暴力的搜辣,加上记忆化剪枝,大大的好!
先预处理出可以流出去的位置们,然后对于每一个位置暴力bfs它们的所有路径QAQ,记忆化剪枝效果非常好了QAQ

很有道理的样子呢QAQ
我们要找的实际上就是每个点出去的每条路径上最大值的最小值,而想到最小生成树就是满足这个性质,最大边最小。
所以按边权排序加边,两个联通块中如果一个已经有出去的节点,另一个没有,那么更新没有的那个联通块的答案就是这条新加的边权。
吼麻烦啊QAQ
#include<bits/stdc++.h>
using namespace std; int h[][], n, m;
int dx[] = {, , , -}, dy[] = {, -, , }; inline void read(int &x) {
x = ; int t = ; char ch = getchar();
while(ch > '' || ch < '') { if(ch == '-') t = -; ch = getchar(); }
while(ch >= '' && ch <= '') { x = x * + ch - ''; ch = getchar(); }
x *= t;
} bool check(int x, int y) {
return x >= && y >= && x <= n + && y <= m + ;
} int vis[][], vis1[][], ans[][];
int idc, tmp;
void dfr(int x, int y) {
if(vis[x][y]) return ;
vis[x][y] = ;
for(int k = ; k < ; k ++) {
int xx = x + dx[k], yy = y + dy[k];
if(!check(xx, yy)) ans[x][y] = ;
else if(h[xx][yy] <= h[x][y]) {
dfr(xx, yy);
if(ans[xx][yy] == ) ans[x][y] = ;
}
}
} bool dfs(int x, int y, int u) {
if(vis1[x][y] == idc) return ;
if(h[x][y] > u) {
tmp = min(tmp, h[x][y] + ans[x][y]);
return ;
}
if(ans[x][y] == ) return ;
vis1[x][y] = idc;
for(int k = ; k < ; k ++) {
int xx = x + dx[k], yy = y + dy[k];
if(!dfs(xx, yy, u)) return ;
}
return ;
} struct Point {
int x, y, h;
bool operator < (const Point &t) const {
return h > t.h;
}
} points[ * ]; int main() {
freopen("water.in", "r", stdin);
freopen("water.out", "w", stdout);
scanf("%d%d", &n, &m);
for(int i = ; i <= n; i ++)
for(int j = ; j <= m; j ++) {
read(h[i][j]);
points[(i - ) * m + j] = (Point) {i, j, h[i][j]};
}
sort(points + , points + + n * m);
memset(ans, -, sizeof(ans));
for(int i = ; i <= n; i ++)
for(int j = ; j <= m; j ++) dfr(i, j);
for(int i = ; i <= n * m; i ++) {
idc ++;
tmp = 0x3f3f3f3f;
if(!dfs(points[i].x, points[i].y, points[i].h))
ans[points[i].x][points[i].y] = ;
else ans[points[i].x][points[i].y] = tmp - points[i].h;
}
for(int i = ; i <= n; i ++) {
for(int j = ; j <= m; j ++) printf("%d ", ans[i][j]);
printf("\n");
}
return ;
}
【10.26校内测试】【状压?DP】【最小生成树?搜索?】的更多相关文章
- 相邻行列相互影响的状态类问题(类似状压dp的搜索)(POJ3279)
POJ3279http://poj.org/problem?id=3279 题意:黑白的板,每次选择一个十字形翻转(十字板内黑白互换,若是边界则不管),求最小将原图变为全白的策略. 这是一道对于每个格 ...
- 【10.5校内测试】【DP】【概率】
转移都很明显的一道DP题.按照不优化的思路,定义状态$dp[i][j][0/1]$表示吃到第$i$天,当前胃容量为$j$,前一天吃(1)或不吃(0)时能够得到的最大价值. 因为有一个两天不吃可以复原容 ...
- 你必须知道的基本位运算技巧(状压DP、搜索优化都会用到)
一. 位操作基础 基本的位操作符有与.或.异或.取反.左移.右移这6种,它们的运算规则如下所示: 符号 描述 运算规则 & 与 两个位都为1时,结果才为1 | 或 两个位都为0时,结果才为0 ...
- [POJ1038]状压DP
题意:给一个n*m的区域,里面有一些障碍物,往里面放2*3和3*2的矩形,矩形之间不能重叠,不能覆盖到障碍物,求能放置的最大个数.(n<=150,m<=10) 思路:看到m=10就应该往状 ...
- 关灯问题II 状压DP
关灯问题II 状压DP \(n\)个灯,\(m\)个按钮,每个按钮都会对每个灯有不同影响,问最少多少次使灯熄完. \(n\le 10,m\le 100\) 状压DP的好题,体现了状压的基本套路与二进制 ...
- 【62测试】【状压dp】【dfs序】【线段树】
第一题: 给出一个长度不超过100只包含'B'和'R'的字符串,将其无限重复下去. 比如,BBRB则会形成 BBRBBBRBBBRB 现在给出一个区间[l,r]询问该区间内有多少个字符'B'(区间下标 ...
- tyvj 2054 [Nescafé29]四叶草魔杖——最小生成树+状压dp
题目:http://www.joyoi.cn/problem/tyvj-2054 枚举点集,如果其和为0,则作为一个独立的块求一下最小生成树.因为它可以不和别的块连边. 然后状压dp即可. 别忘了判断 ...
- [tyvj2054] 四叶草魔杖 (最小生成树 状压dp)
传送门 Background 陶醉在彩虹光芒笼罩的美景之中,探险队员们不知不觉已经穿过了七色虹,到达了目的地,面前出现了一座城堡和小溪田园,城堡前的木牌上写着"Poetic Island&q ...
- 2018.12.26 考试(哈希,二分,状压dp)
T1 传送门 解题思路 发现有一个限制是每个字母都必须相等,那么就可以转化成首尾的差值相等,然后就可以求出\(k-1\)位的差值\(hash\)一下.\(k\)为字符集大小,时间复杂度为\(O(nk) ...
随机推荐
- Android获取手机分辨率DisplayMetircs类
关于Android中手机分辨率的使用 Android 可设置为随着窗口大小调整缩放比例,但即便如此,手机程序设计人员还是必须知道手机屏幕的边界,以避免缩放造成的布局变形问题. 手机的分辨率信息是手机的 ...
- 【NOIP题解】NOIP2017 TG D2T3 列队
列队,NOIP2017 TG D2T3. 树状数组经典题. 题目链接:洛谷. 题意: Sylvia 是一个热爱学习的女孩子. 前段时间,Sylvia 参加了学校的军训.众所周知,军训的时候需要站方阵. ...
- java map遍历并删除特定值
删除map中包含password和username的键值对 若是在map中直接删除,会指针错误 Iterator<Map.Entry<String,Object>> it = ...
- LCD时序中设计到的VSPW/VBPD/VFPD/HSPW/HBPD/HFPD总结【转】
转自:https://blog.csdn.net/u011603302/article/details/50732406 下面是我在网上摘录的一些关于LCD信号所需时钟的一些介绍, 描述方式一: 来自 ...
- 2->集群架构主机优化流程
集群架构优化流程: 有道笔记分享链接
- 目标板通过nfs挂载根文件系统
目标板挂载根文件系统的方法有两种(这里所说的服务端就是ubuntu,Ubuntu已经成功安装了nfs服务,并且保证服务端与目标板ping 通) 第一种:等待开发板启动之后去挂载,此时文件系统从Flas ...
- 编写组件TComponent published $M+ 问题
报错如下: PUBLISHED caused RTTI ($M+) to be added to type 修改成下面这样之后: 解决问题 方法: 来自:http://www.cnblogs.com/ ...
- Extjs 代码拾穗
1.tree grid 添加一行 var rootNode = store.getRootNode(); var newRecord = Ext.create('MatrixDlv',{"s ...
- 配置sql server 2000以允许远程访问
配置sql server 2000以允许远程访问适合故障:1. 用sql企业管理器能访问sql server 2000(因为它是采用命名管道(named pipes)方式进行方式),但用ado.net ...
- webpack性能优化-实战
题外话:年初项目重构上线,项目技术栈使用vue+webpack,测试执行整个打包流程需要10分钟,同时又因涉及三个渠道,部署好环境就需半个小时,这严重延误了上线进度,因此提高webpack构建效率,成 ...