3 1 2 3 1 2 3 1 2 3 3 1 1 1 1 1 1 1 1 1
1 6题意比较坑。。问从(1,1)到(n,n)能走的路径数。规定从一点(x,y)到相邻的4个点能走的条件是该点到(n,n)的最短距离大于要到达的那个点距离(n,n)的最短距离 (最短距离可用bfs生成。。)然后爆搜即可。。要用到记忆化来加速搜索。。其中 dp[i][j] 代表在点(i,j)时满足答案的部分解。这样回溯的时候会很节省时间。。还有。。要用%I64d...#include <cstdio> #include <iostream> #include <algorithm> #include <cstring> #include <cctype> #include <cmath> #include <cstdlib> #include <vector> #include <queue> #include <set> #include <map> #include <list> #define ll __int64 #define pp pair<int,int> using namespace std; const int INF = 0x3f3f3f3f; ll dp[52][52],ma[52][52],dis[52][52]; int n,dir[4][2]={{0,1},{0,-1},{1,0},{-1,0}}; void bfs() { queue < pp > Q; dis[n][n]=ma[n][n]; Q.push(make_pair(n,n)); while(!Q.empty()) { pp t=Q.front();Q.pop(); for(int i=0;i<4;i++) { int tx=t.first+dir[i][0]; int ty=t.second+dir[i][1]; if(tx<1||tx>n||ty<1||ty>n) continue; if(dis[tx][ty]==-1||dis[tx][ty]>dis[t.first][t.second]+ma[tx][ty]) { dis[tx][ty]=dis[t.first][t.second]+ma[tx][ty]; Q.push(make_pair(tx,ty)); } } } } ll dfs(int x,int y) { if(dp[x][y]) return dp[x][y]; if(x==n&&y==n) return 1; for(int i=0;i<4;i++) { int tx=dir[i][0]+x; int ty=dir[i][1]+y; if(tx>=1&&tx<=n&&ty>=1&&ty<=n&&dis[tx][ty]<dis[x][y]) dp[x][y]+=dfs(tx,ty); } return dp[x][y]; } int main() { while(~scanf("%d",&n)) { for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) scanf("%I64d",&ma[i][j]); memset(dp,0,sizeof(dp)); memset(dis,-1,sizeof(dis)); bfs(); dfs(1,1); printf("%I64d\n",dp[1][1]); } return 0; }
原文地址:http://blog.csdn.net/qq_16255321/article/details/40798229