题目链接:P1535 [USACO08MAR]Cow Travelling S
题目分析:
- 奶牛总是在移动,所以时间不停止,它也不停止,那么当刚好T秒的时候,它在终点的路径就是一条方案
- 奶牛移动的路径可以自交(在当前移动的路径里,可以重复移动)
- 求所有方案数,可以减少搜索量,进行对已经搜索过的状态记录,用记忆化搜索
- 可行性剪枝:
- 因为两点是确定的,忽略障碍物,可以得到它们两点最短路径为abs(x1-x2) + abs(y1-y2),剪枝:当前时间+最短路径所需时间 > 时间T
- 超过t秒的进行剪枝
记忆化搜索:
#include<iostream>
using namespace std;
const int N = 110;
int n,m,t;
char g[N][N];
int st[N][N][N];
int dx[4] = {0,1,0,-1};
int dy[4] = {1,0,-1,0};
int xa,ya,xb,yb;
int ans;
int dfs(int x,int y,int d){
//超过时间t
if(d > t) return 0;
//当前时间+最短路径所需时间 > 时间T
if(d + abs(x - xb) + abs(y - yb) > t) return 0;
if(x == xb && y == yb && d == t){
return 1;
}
if(st[x][y][d]) return st[x][y][d];
int u = 0;
for(int i = 0; i < 4; i ++ ){
int a = x + dx[i];
int b = y + dy[i];
if(a < 1 || a > n || b < 1 || b > m) continue;
if(g[a][b] == '*') continue;
u += dfs(a,b,d + 1);
}
st[x][y][d] = u;
ans = u;
return u;
}
int main() {
cin >> n >> m >> t;
for(int i = 1; i <= n; i ++ ){
for(int j = 1; j <= m; j ++ ){
cin >> g[i][j];
}
}
cin >> xa >> ya >> xb >> yb;
dfs(xa,ya,0);
cout<<ans<<endl;
return 0;
}