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】【最小生成树?搜索?】的更多相关文章

  1. 相邻行列相互影响的状态类问题(类似状压dp的搜索)(POJ3279)

    POJ3279http://poj.org/problem?id=3279 题意:黑白的板,每次选择一个十字形翻转(十字板内黑白互换,若是边界则不管),求最小将原图变为全白的策略. 这是一道对于每个格 ...

  2. 【10.5校内测试】【DP】【概率】

    转移都很明显的一道DP题.按照不优化的思路,定义状态$dp[i][j][0/1]$表示吃到第$i$天,当前胃容量为$j$,前一天吃(1)或不吃(0)时能够得到的最大价值. 因为有一个两天不吃可以复原容 ...

  3. 你必须知道的基本位运算技巧(状压DP、搜索优化都会用到)

    一. 位操作基础 基本的位操作符有与.或.异或.取反.左移.右移这6种,它们的运算规则如下所示: 符号 描述 运算规则 & 与 两个位都为1时,结果才为1 | 或 两个位都为0时,结果才为0 ...

  4. [POJ1038]状压DP

    题意:给一个n*m的区域,里面有一些障碍物,往里面放2*3和3*2的矩形,矩形之间不能重叠,不能覆盖到障碍物,求能放置的最大个数.(n<=150,m<=10) 思路:看到m=10就应该往状 ...

  5. 关灯问题II 状压DP

    关灯问题II 状压DP \(n\)个灯,\(m\)个按钮,每个按钮都会对每个灯有不同影响,问最少多少次使灯熄完. \(n\le 10,m\le 100\) 状压DP的好题,体现了状压的基本套路与二进制 ...

  6. 【62测试】【状压dp】【dfs序】【线段树】

    第一题: 给出一个长度不超过100只包含'B'和'R'的字符串,将其无限重复下去. 比如,BBRB则会形成 BBRBBBRBBBRB 现在给出一个区间[l,r]询问该区间内有多少个字符'B'(区间下标 ...

  7. tyvj 2054 [Nescafé29]四叶草魔杖——最小生成树+状压dp

    题目:http://www.joyoi.cn/problem/tyvj-2054 枚举点集,如果其和为0,则作为一个独立的块求一下最小生成树.因为它可以不和别的块连边. 然后状压dp即可. 别忘了判断 ...

  8. [tyvj2054] 四叶草魔杖 (最小生成树 状压dp)

    传送门 Background 陶醉在彩虹光芒笼罩的美景之中,探险队员们不知不觉已经穿过了七色虹,到达了目的地,面前出现了一座城堡和小溪田园,城堡前的木牌上写着"Poetic Island&q ...

  9. 2018.12.26 考试(哈希,二分,状压dp)

    T1 传送门 解题思路 发现有一个限制是每个字母都必须相等,那么就可以转化成首尾的差值相等,然后就可以求出\(k-1\)位的差值\(hash\)一下.\(k\)为字符集大小,时间复杂度为\(O(nk) ...

随机推荐

  1. 10 Useeful Tips for Writing Effective Bash Scripts in Linux

    1.Always Use Comments in Scripts2.Make a Scripts exit When Fails    Sometimes bash may continue to e ...

  2. 脚本病毒分析扫描专题1-VBA代码阅读扫盲、宏病毒分析

    1.Office Macor MS office宏的编程语言是Visual Basic For Applications(VBA). 微软在1994年发行的Excel5.0版本中,即具备了VBA的宏功 ...

  3. trace spring

    package xx.com.aspect; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotati ...

  4. github 优秀的开源项目

    https://github.com/wlcaption/AndroidMarket---- 这是手机应用商店,包含应用的下载,用户中心等内容 https://github.com/wlcaption ...

  5. 使用离线包部署kubernetes 1.9.0、kubernetes-dashboard 1.8

    =============================================== 2018/3/22_第2次修改                       ccb_warlock 更新 ...

  6. 将python脚本转换成exe文件--pyinstaller

    遇到的大坑: 直接运行python文件效果:         执行 pyinstaller  -F -w  -p  -i ./123.ico  ./main.py    在dict文件夹下生成exe文 ...

  7. Fiddler 4 抓包(APP HTTPS )

    一.手机连接Fiddler 1.配置fiddler 1.安装fiddler,基本下一步下一步即可: 2.打开fiddler,点击顶部栏Tools——>Options 3.在HTTPS页签勾选“D ...

  8. Jquery获取radio单选按钮的value与后面的文字

    一组单选按钮如图: <input name="classId" value="8afa94f45ba3e2c1015ba3fac6c00000" type ...

  9. ubuntu 创建容器 并ssh 连接容器

    1.下载镜像:docker search ubuntu docker pull ubuntu 2. 创建容器 docker run --name spider_frame -p 8888:8888 - ...

  10. Kubernetes 部署kafka ACL(单机版)

    一.概述 在Kafka0.9版本之前,Kafka集群时没有安全机制的.Kafka Client应用可以通过连接Zookeeper地址,例如zk1:2181:zk2:2181,zk3:2181等.来获取 ...