【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) ...
随机推荐
- Redis简介——(一)
1.关于关系型数据库和nosql数据库 关系型数据库是基于关系表的数据库,最终会将数据持久化到磁盘上,而nosql数据 库是基于特殊的结构,并将数据存储到内存的数据库.从性能上而言,nosql数据库 ...
- python基础===一行 Python 代码实现并行(转)
原文:https://medium.com/building-things-on-the-internet/40e9b2b36148 译文:https://segmentfault.com/a/119 ...
- python基础-类的属性(类属性,实例属性,私有属性)
一:类的属性 类的属性分为:类属性(公有属性),实例属性和私有属性. 1)类属性(公有属性(静态字段): 类定义时直接指定的属性(不是在__init__方法中),可以通过类名直接访问属性,并且保存 ...
- 使用Dockerfile构建docker lnmp环境
一.mysql 1.创建 Dockerfile mkdir mysql # 创建一个目录存放之后的Dockerfile,目录名无所谓 cd mysql # 进入目录 vi Dockerfile # 创 ...
- delphi TComponent类 2
来自:http://blog.csdn.net/lailai186/article/details/7442385 ------------------------------------------ ...
- [新手]在macOS环境下安装xdebug
使用环境 masOS 10.12 使用MAMP安装的PHP环境 在新安装的系统中,安装xdebug,遇到了一些小问题; P.S. 重新按照xdebug官网的指南安装了一次,把上次安装失败的xd ...
- mvn本地库导入jar包
导入脚本 #!/bin/sh mvn deploy:deploy-file -DgroupId=com.xxx.xxx -DartifactId=包名 -Dversion=4.0 -Dpackag ...
- android拾遗——AlarmManager的使用
AlarmManager的作用文档中的解释是:在特定的时刻为我们广播一个指定的Intent.简单的说就是我们设定一个时间,然后在该时间到来时,AlarmManager为我们广播一个我们设定的Inten ...
- Java第三阶段学习(一、IO流------File类)
一.IO概述: 把内存中的数据存入到硬盘(持久化设备)中叫做:输出(写)Output操作.JAVA软件往电脑硬盘上走叫输出. 把硬盘中的数据读取到到内存里叫做:输入(读)Input操作.电脑硬盘上往J ...
- vuejs、eggjs、mqtt全栈式开发设备管理系统
vuejs.eggjs.mqtt全栈式开发简单设备管理系统 业余时间用eggjs.vuejs开发了一个设备管理系统,通过mqtt协议上传设备数据至web端实时展现,包含设备参数分析.发送设备报警等模块 ...