Codeforces Round #355 (Div. 2) D. Vanya and Treasure dp+分块
题目链接:
http://codeforces.com/contest/677/problem/D
题意:
让你求最短的从start->...->1->...->2->...->3->...->...->p的最短路径。
题解:
这题dp的阶段性还是很明显的,相同的值得方格为同一个阶段,然后求从阶段1->2->3...->p的阶段图最短路。
初始化所有a[x][y]==1的格子为起始点到(x,y)坐标的距离。
方程式为dp[x1][y1]=min(dp[x1][y1],dp[x2][y2]+abs(x2-x1)+abs(y2-y1)),其中a[x1][y1]=a[x2][y2]+1。
但是这要n*n*m*m的复杂度。
x阶段到x+1阶段的转移数为cnt[x]*cnt[x+1],这个太大,并且多来几个就会爆了,但注意如果cnt[x]*cnt[x+1]大了,其他的如
cnt[x']*cnt[x'+1]就有可能会变小,因为sum(cnt[i])是固定的,
那么根据这个特性,我们可以考虑分块!,当cnt[x]*cnt[x+1]<=m*n的时候直接暴力,如果大了就用最短路(spfa就可以)
这样跑出来的时间复杂度为O(n*m*sqrt(n*m)*log(n*m)),那个log(n*m)是spfa跑出来的。
具体的均摊时间复杂度证明:http://codeforces.com/blog/entry/45181?#comment-297475
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<utility>
#include<vector>
#include<algorithm>
#include<queue>
#define mp make_pair
#define X first
#define Y second
using namespace std; const int maxn = ; int dp[maxn][maxn],mat[maxn][maxn];
int cnt[maxn*maxn],inq[maxn][maxn],d[maxn][maxn];
vector<pair<int,int> > G[maxn*maxn];
int n, m, p; inline int get_dis(int x1, int y1, int x2, int y2) {
return abs(x1 - x2) + abs(y1 - y2);
} const int dx[] = { -,,, };
const int dy[] = { ,,-, }; void init() {
memset(dp, 0x7f, sizeof(dp));
memset(cnt, , sizeof(cnt));
} int main() {
while (scanf("%d%d%d", &n, &m, &p) == && n) {
init();
int xt, yt;
for (int i = ; i < n; i++) {
for (int j = ; j < m; j++) {
scanf("%d", &mat[i][j]);
if (mat[i][j] == ) dp[i][j] = get_dis(,,i,j);
if (mat[i][j] == p) xt = i, yt = j;
cnt[mat[i][j]]++;
G[mat[i][j]].push_back(mp(i, j));
}
}
for (int i = ; i <= p; i++) {
if (cnt[i - ] * cnt[i] <= m*n) {
for (int j = ; j < G[i].size(); j++) {
int x2 = G[i][j].X, y2 = G[i][j].Y;
for (int k = ; k < G[i - ].size(); k++) {
int x1 = G[i - ][k].X, y1 = G[i - ][k].Y;
dp[x2][y2] = min(dp[x2][y2], dp[x1][y1] + get_dis(x1, y1, x2, y2));
}
}
}
else {
memset(d, 0x7f, sizeof(d));
memset(inq, , sizeof(inq));
queue<pair<int, int> > Q;
for (int j = ; j < G[i - ].size(); j++) {
pair<int, int> u = G[i - ][j];
d[u.X][u.Y] = dp[u.X][u.Y], inq[u.X][u.Y] = ;
Q.push(mp(u.X, u.Y));
}
while (!Q.empty()) {
pair<int, int> u = Q.front(); Q.pop();
inq[u.X][u.Y] = ;
if (mat[u.X][u.Y] == i) dp[u.X][u.Y] = min(dp[u.X][u.Y], d[u.X][u.Y]);
for (int j = ; j < ; j++) {
int x = u.X + dx[j], y = u.Y + dy[j];
if (x < || x >= n || y < || y >= m) continue;
if (d[x][y] > d[u.X][u.Y] + ) {
d[x][y] = d[u.X][u.Y] + ;
if (!inq[x][y]) inq[x][y] = , Q.push(mp(x, y));
}
}
}
}
}
printf("%d\n", dp[xt][yt]);
}
return ;
}
Codeforces Round #355 (Div. 2) D. Vanya and Treasure dp+分块的更多相关文章
- Codeforces Round #355 (Div. 2) D. Vanya and Treasure 分治暴力
D. Vanya and Treasure 题目连接: http://www.codeforces.com/contest/677/problem/D Description Vanya is in ...
- Codeforces Round #355 (Div. 2) D. Vanya and Treasure
题目大意: 给你一个n × m 的图,有p种宝箱, 每个点上有一个种类为a[ i ][ j ]的宝箱,a[ i ][ j ] 的宝箱里有 a[ i ][ j ] + 1的钥匙,第一种宝箱是没有锁的, ...
- Codeforces Round #355 (Div. 2) C. Vanya and Label 水题
C. Vanya and Label 题目连接: http://www.codeforces.com/contest/677/problem/C Description While walking d ...
- Codeforces Round #355 (Div. 2) B. Vanya and Food Processor 水题
B. Vanya and Food Processor 题目连接: http://www.codeforces.com/contest/677/problem/B Description Vanya ...
- Codeforces Round #355 (Div. 2) A. Vanya and Fence 水题
A. Vanya and Fence 题目连接: http://www.codeforces.com/contest/677/problem/A Description Vanya and his f ...
- Codeforces Round #355 (Div. 2)-B. Vanya and Food Processor,纯考思路~~
B. Vanya and Food Processor time limit per test 1 second memory limit per test 256 megabytes input s ...
- Codeforces Round #355 (Div. 2)C - Vanya and Label
啊啊啊啊啊啊啊,真的是智障了... 这种题目,没有必要纠结来源.只要知道它的结果的导致直接原因?反正这句话就我听的懂吧... ">>"/"&" ...
- Codeforces Round #355 (Div. 2) B. Vanya and Food Processor
菜菜菜!!!这么撒比的模拟题,听厂长在一边比比比了半天,自己想一想,然后纯模拟一下,中间过程检测一下,妥妥的就可以过. 题意:有N个东西要去搞碎,每个东西有一个高度,然后有一台机器支持里面可以达到的最 ...
- 水题 Codeforces Round #308 (Div. 2) A. Vanya and Table
题目传送门 /* 水题:读懂题目就能做 */ #include <cstdio> #include <iostream> #include <algorithm> ...
随机推荐
- SQL事务隔离级别
数据库是要被广大客户所共享访问的,那么在数据库操作过程中很可能出现以下几种不确定情况. 更新丢失(Lost update) 两个事务都同时更新一行数据,但是第二个事务却中途失败退出,导致对数据的两个修 ...
- MVC自定义错误页404静态页
昨天公司要求给所有项目添加自定义404错误页,具体的要求实现的有以下几点: 1.实现自定义错误(如各种error,404等)跳转到指定的页面 2.所指定的页面输出的http状态值必须是404或其他指定 ...
- cocos2dx2.2.2弹出框的实现
在上一篇文章中,我们利用CCEditBox实现了输入框功能,使我们在注册时可以输入用户名和密码.但是当用户名和密码的输入不符合规范时,我们应该怎样给与用户提示呢?下面我们就来介绍弹出框的实现方式. 我 ...
- 追访现代主流程序员的家庭事业观---禅宗派程序员KUROKY
Kuroky,一个被人遗忘的当代主流程序员. 在他的内心深处有着怎样的心路历程 他的快乐与悲伤,都是一个禅 独家专访kuroky: 记者:作为现代主流程序员,你内心的苦楚玉欢乐通过什么来发现? 大师: ...
- WCF之实例模型
PerCall. 为每次调用创建新的服务对象. 内存使用量最小,增加整体的吞吐量. 状态不保存,服务实例及时释放. 单例的状态没有办法保存.所以应使用数据库或者文件或者全局变量来保存服务实例的状态.如 ...
- WCF之Host宿主
Self_hosting自托管宿主. 过程:手动创建Host实例,把服务端点添加到Host实例上,把服务接口与Host关联. 一个Host只能指定一个服务类型,但是可以添加多个服务端点,也可以打开多个 ...
- JavaScript之字符串
一.声明方式 1. 直接赋值 var str = 'hello javascript'; 2. 构造函数 var str2 = new String('hello world'); 这两种有什么区别呢 ...
- Error: An App ID with identifier "*****" is not avaliable. Please enter a different string.
Error: An App ID with identifier "*****" is not avaliable. Please enter a different string ...
- UINavigationController的popViewControllerAnimated问题
UINavigationController是IOS编程中的一个view controller的容器,通过栈管理viewControllers,每一次push操作都将在栈顶添加一个view contr ...
- iOS ARC下循环引用的问题 -举例说明strong和weak的区别
strong:适用于OC对象,作用和非ARC中的retain作用相同,它修饰的成员变量为强指针类型weak:适用于OC对象,作用和非ARC中的assign作用相同,修饰的成员变量为弱指针类型assig ...