HDU - 1428【bfs+记忆化】

点击查看详情——《IJCAI 2017 口碑商家客流量预测大赛》

漫步校园

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 4205    Accepted Submission(s): 1317

Problem Description

LL最近沉迷于AC不能自拔,每天寝室、机房两点一线。由于长时间坐在电脑边,缺乏运动。他决定充分利用每次从寝室到机房的时间,在校园里散散步。整个HDU校园呈方形布局,可划分为n*n个小方格,代表各个区域。例如LL居住的18号宿舍位于校园的西北角,即方格(1,1)代表的地方,而机房所在的第三实验楼处于东南端的(n,n)。因有多条路线可以选择,LL希望每次的散步路线都不一样。另外,他考虑从A区域到B区域仅当存在一条从B到机房的路线比任何一条从A到机房的路线更近(否则可能永远都到不了机房了…)。现在他想知道的是,所有满足要求的路线一共有多少条。你能告诉他吗?

Input

每组测试数据的第一行为n(2=<n<=50),接下来的n行每行有n个数,代表经过每个区域所花的时间t(0<t<=50)(由于寝室与机房均在三楼,故起点与终点也得费时)。

Output

针对每组测试数据,输出总的路线数(小于2^63)。

Sample Input

3
1 2 3
1 2 3
1 2 3
3
1 1 1
1 1 1
1 1 1

Sample Output

1
6

题意:

找 (1,1)->(n,n)有多少种路径,每一步往下一步走的时候,满足下一步到(n, n)的距离比当前到(n, n)的距离短;

题解:

bfs预处理所有点到(n, n)的距离,然后记忆化dfs

代码:

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <cstring>
 4 #include <cstdio>
 5 #include <bitset>
 6 #include <vector>
 7 #include <queue>
 8 #include <stack>
 9 #include <cmath>
10 #include <list>
11 #include <set>
12 #include <map>
13 #define rep(i,a,b) for(int i = a;i <= b;++ i)
14 #define per(i,a,b) for(int i = a;i >= b;-- i)
15 #define mem(a,b) memset((a),(b),sizeof((a)))
16 #define FIN freopen("in.txt","r",stdin)
17 #define FOUT freopen("out.txt","w",stdout)
18 #define IO ios_base::sync_with_stdio(0),cin.tie(0)
19 #define mid ((l+r)>>1)
20 #define ls (id<<1)
21 #define rs ((id<<1)|1)
22 #define N 55
23 #define INF 0x3f3f3f3f
24 #define INFF ((1LL<<62)-1)
25 using namespace std;
26 typedef long long LL;
27 typedef pair<int, int> PIR;
28 const double eps = 1e-8;
29
30 int n, G[N][N], dis[N][N], dir[4][2] = {0,1,0,-1,1,0,-1,0};
31 LL dp[N][N];
32 bool vis[N][N];
33 struct Node{
34     int x, y, c;
35     Node(int _x, int _y, int _c)    { x = _x; y = _y; c = _c; }
36     bool operator < (const Node &r) const   { return c > r.c; }
37 };
38 bool judge(int x, int y){
39     if(x < 1 || x > n || y < 1 || y > n)    return false;
40     return true;
41 }
42 void bfs(){
43     priority_queue <Node> Q;
44     mem(dis, INF);
45     mem(vis, false);
46     Q.push(Node(n, n, G[n][n]));
47     dis[n][n] = G[n][n];
48     while(!Q.empty()){
49         Node h = Q.top();
50         Q.pop();
51         int xx = h.x, yy = h.y;
52         if(vis[xx][yy]) continue;
53         vis[xx][yy] = true;
54         rep(i, 0, 3){
55             int xi = xx+dir[i][0], yi = yy+dir[i][1];
56             if(judge(xi, yi) && dis[xx][yy]+G[xi][yi] < dis[xi][yi]){
57                 dis[xi][yi] = dis[xx][yy]+G[xi][yi];
58                 Q.push(Node(xi, yi, dis[xi][yi]));
59             }
60         }
61     }
62     return ;
63 }
64 LL dfs(int x, int y){
65     if(dp[x][y])    return dp[x][y];
66     rep(i, 0, 3){
67         int xi = x+dir[i][0], yi = y+dir[i][1];
68         if(judge(xi, yi) && dis[x][y] > dis[xi][yi]){
69             dp[x][y] += dfs(xi, yi);
70         }
71     }
72     return dp[x][y];
73 }
74 int main()
75 {IO;
76     //FIN;
77     while(cin >> n){
78         rep(i, 1, n){
79             rep(j, 1, n)    cin >> G[i][j];
80
81         }
82         bfs();
83         mem(dp, 0);
84         dp[n][n] = 1;
85         dfs(1, 1);
86         cout << dp[1][1] << endl;
87     }
88     return 0;
89 }

时间: 2024-10-19 17:53:25

HDU - 1428【bfs+记忆化】的相关文章

HDU 1429 (BFS+记忆化状压搜索)

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1429 题目大意:最短时间内出迷宫,可以走回头路,迷宫内有不同的门,对应不同的钥匙. 解题思路: 要是没有门和钥匙,而且不能走回头路,就是个简单粗暴的BFS. 有了门之后,就要状态压缩+记忆化搜索.不然这个图会搜死你. 本题的状态压缩基于一个事实:尽管可以走回头路,但是回头是有理由的,你要么开了门,要么拿了钥匙,使状态发生改变. 否则等于多绕了一步,浪费时间,应该及时剪枝. f[x][y][key]

HDU 5025 (BFS+记忆化状压搜索)

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5025 题目大意: 迷宫中孙悟空救唐僧,可以走回头路.必须收集完钥匙,且必须按顺序收集.迷宫中还有蛇,杀蛇多耗时1,蛇杀完就没了.问最少耗时. 解题思路: 2014广州网赛的水题之一.当时没刷过BFS状压,结果悲剧了. 首先这题可以压钥匙,也可以压蛇,不过压钥匙内存岌岌可危,于是就压蛇吧. 设f[x][y][key][snake]为在(x,y)点,已经取得的钥匙key,以及杀蛇snake的状态. 对

FZU 2092 收集水晶 bfs+记忆化搜索 or 暴力

题目链接:收集水晶 一眼看过去,觉得是普通的bfs,初始位置有两个.仔细想了想...好像如果这样的话..........[不知道怎么说...T_T] dp[12][12][12][12][210] 中dp[x1][y1][x2][y2][t] =value 表示t时刻人和影子分别到x1,y1 和x2, y2位置的时候得到的最大价值是value. 然后呢,因为每个点的状态一定是由它相邻的状态确定的,所以由dp[0][0][0][0][0] = 0就可以得到所有的状态,中间记录最大值即为ans. 这

HDU 1428 漫步校园 (BFS + 记忆化搜索)

漫步校园 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 3360    Accepted Submission(s): 1009 Problem Description LL最近沉迷于AC不能自拔,每天寝室.机房两点一线.由于长时间坐在电脑边,缺乏运动.他决定充分利用每次从寝室到机房的时间,在校园里散散步.整个HDU校园呈方形布局,可

noip 01迷宫(BFS+记忆化)

题目链接:https://www.luogu.org/problem/show?pid=1141 题意:给出一个仅由数字0与1组成的n×n格迷宫.放0的那一格可以4个方向走到放1那一格,1也是四个方向走到放0的那一格.算上本身的那格.求最多能移动多少格子. 数据比较大,如果直接用bfs搜的话会暴时.所以需要每次搜索完都记录一下. 1 #include <iostream> 2 #include <algorithm> 3 #include <queue> 4 using

HDU 4597(记忆化搜索 dfs 参考)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4597 Problem Description Alice and Bob are playing a game. There are two piles of cards. There are N cards in each pile, and each card has a score. They take turns to pick up the top or bottom card from

【BZOJ 1415】 1415: [Noi2005]聪聪和可可 (bfs+记忆化搜索+期望)

1415: [Noi2005]聪聪和可可 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1640  Solved: 962 Description Input 数据的第1行为两个整数N和E,以空格分隔,分别表示森林中的景点数和连接相邻景点的路的条数. 第2行包含两个整数C和M,以空格分隔,分别表示初始时聪聪和可可所在的景点的编号. 接下来E行,每行两个整数,第i+2行的两个整数Ai和Bi表示景点Ai和景点Bi之间有一条路. 所有的路都是无向的,即

FZU 2092 bfs+记忆化搜索

晚上团队训练赛的题 和普通bfs不同的是 这是同时操纵人与影子两个单位进行的bfs 由于可能发生人和影子同时接触水晶 所以不可以分开操作 当时使用node记录人和影子的位置 然后进行两重for循环来分别改变位置 结果超内存 分析了一下应该是队列超了内存 毕竟如果每个点都存入的话一个点最多可以衍生出25个node 然后t最大为200s 一定会超 之间还发生了一些并不能理解的bug 被逼到最后重构才拿到了一个超内存 名次也不好 急需一个ac来赶上去 简直要烧起来了 侧面反映心理素质还是差一些 当时未

FZU 2092 收集水晶 BFS记忆化搜索

用了两个pii代码有点长…… 记忆化搜索主要还是用用dp数组去记录并更新状态 1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<cmath> 5 #include<cstring> 6 #include<string> 7 #include<ctime> 8 #include<map> 9 #include<s