3 1 2 3 1 2 3 1 2 3 3 1 1 1 1 1 1 1 1 1
1 6
题意首先得弄清楚!意思是从左上角开始起步,每次走到的下一个位置要比原位置到终点距离更大,也就是说每走一步都要离终点更近!!题意很关键!
显然预处理就是求每个点到终点最短距离,这个很水吧!spfa搞定!(我代码里面的函数取名字取的bfs,其实个人认为spfa只是比bfs效率高点儿,本质没区别!)
接下来必须记忆化搜索了,
深搜的效率真的是很低啊!!!这题刚开始打算直接深搜搞定的结果硬是没成功,呵呵呵。。
记忆化搜索其实就是所谓的dp,写起来也挺简单的,易于理解!
#include<iostream> #include<stdio.h> #include<string.h> using namespace std; typedef long long ll; struct data { int x,y; }q[10000]; const int inf=100000000; int a[55][55];int n; ll s[55][55],dp[55][55]; bool spfa[55][55]; int fx[4][2]={{0,1},{1,0},{-1,0},{0,-1}}; void bfs() { for(int i=0;i<55;i++) for(int j=0;j<55;j++) dp[i][j]=inf; dp[n-1][n-1]=a[n-1][n-1]; int r=0,l=0; q[r].x=n-1,q[r++].y=n-1; //int f=0; while(l<=r) { //f++; //if(f==10)break; int x=q[l].x,y=q[l].y; spfa[x][y]=0; // cout<<endl; //cout<<x<<' '<<y<<endl; for(int i=0;i<4;i++) { int temx=x+fx[i][0],temy=y+fx[i][1]; //cout<<x<<"->"<<temx<<" "<<y<<"->"<<temy<<endl; if(temx>=0&&temx<n&&temy>=0&&temy<n) { if(dp[temx][temy]>a[temx][temy]+dp[x][y]) { dp[temx][temy]=a[temx][temy]+dp[x][y]; if(spfa[temx][temy]==0) { q[r].x=temx,q[r++].y=temy; spfa[temx][temy]=1; } } } }l++; } } ll dfs(int i,int j) { if(spfa[i][j])return s[i][j]; for(int k=0;k<4;k++) { int temx=i+fx[k][0],temy=j+fx[k][1]; if(temx>=0&&temx<n&&temy>=0&&temy<n) { if(dp[temx][temy]<dp[i][j]) { s[i][j]+=dfs(temx,temy); } } } spfa[i][j]=1; return s[i][j]; } int main() { while(~scanf("%d",&n)) { memset(s,0,sizeof(s)); memset(spfa,0,sizeof(spfa)); for(int i=0;i<n;i++) for(int j=0;j<n;j++) scanf("%d",&a[i][j]); bfs(); s[n-1][n-1]=1; //for(int i=0;i<n;i++){for(int j=0;j<n;j++)cout<<dp[i][j]<<' ';cout<<endl;} printf("%lld\n",dfs(0,0)); } return 0; }