题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=1208
方法1:
正向状态转移,设x,y为当前的位子,设f(x,y)为到达右下角这一目标所需要的方案数,matrix(x,y)是当前可以前进的步数:
f(x,y) =matrix(x,y) == 0 ? 0: ((x,y)处于目标位子 ? 1 :sum(f(x1,y1)| (x1,y1)为(x,y)这一位置横向或纵向能到达的并且在地图里的地方));
原问题的解为 f(0,0)
代码:
#include<iostream> #include<queue> #include<algorithm> #define max 1000001 using namespace std; int n; char map[35][35]; __int64 records[35][35]; __int64 get(int x,int y) { if(x==n-1 && y==n-1 ) return 1; if(x>n-1 || y>n-1 || map[x][y]-'0' ==0 ) return 0; if(records[x][y]!=-1) return records[x][y]; __int64 sum=0; int step = map[x][y]-'0'; sum+=(get(x+step,y)+get(x,y+step)); records[x][y] = sum; return sum; } int main() { while(scanf("%d",&n) && n!=-1) { memset(records,-1,sizeof(records)); for(int i=0;i<n;i++) cin>>map[i]; cout<<get(0,0)<<endl; } return 0; }
方法2:
逆向状态转移,设x,y为横向或纵向可以到达一个目标位置的位子,设f(x,y)为到一位子所需要的方案数,matrix(x,y)是当前可以前进的步数:
f(x,y) = (x,y)为起始位置 ? 1 :sum(f(x1,y1)| (x1,y1)为通过横向或纵向能到达的一目标并且在地图里的位子);
原问题的解为 f(n,n)
代码:
#include<iostream> #include<queue> #include<algorithm> #define max 1000001 using namespace std; int n; char map[35][35]; __int64 records[35][35]; __int64 get(int x,int y) { if(records[x][y]!=-1) return records[x][y]; if(x==0 && map[0][0]-'0'+0 == y) return 1; if(y==0 && map[0][0]-'0'+0 == x) return 1; __int64 sum=0; for(int i=0;i<y;i++) { if(i+map[x][i]-'0' == y) sum+=get(x,i); } for(int i=0;i<x;i++) { if(i+map[i][y]-'0' == x) sum+=get(i,y); } records[x][y] = sum; return sum; } int main() { while(scanf("%d",&n) && n!=-1) { memset(records,-1,sizeof(records)); for(int i=0;i<n;i++) cin>>map[i]; cout<<get(n-1,n-1)<<endl; } return 0; }
感想:简单题