题意:在一个方格图里只能向右和向下走,且每次走的步数只能是方格内的数,求从左上角到右下角最多的路线数。
Analyse:用二维数组a[][]存储图,用dp[i][j]存储走到a[i][j]最多的路线数,dp[i][j]=sigma{dp[x][y](若a[x][y]能走到a[i][j])}。但要实现每个dp[i][j]的计算都不重不漏,需要一个适当的计算顺序。由于只能向右和向下走,所以计算dp[i][j]实际只需先有a[i][j]上面全列的最多路线和左面全排的最多路线,所以可以从dp[0][0]一层一层向外计算,每一层先算上面和左面。
View Code
1 #include<iostream> 2 #include<cstdio> 3 using namespace std; 4 int n; 5 int m[40][40]; 6 __int64 dp[40][40]; 7 int main() 8 { 9 int i,j; 10 while(cin>>n && n!=-1) 11 { 12 for(i=0;i<n;i++) 13 { 14 for(j=0;j<n;j++) 15 { 16 scanf("%1d",&m[i][j]); 17 dp[i][j]=0; 18 } 19 } 20 //由上到下,由左到右 21 dp[0][0]=1; 22 for(i=0;i<n;i++) 23 { 24 for(j=0;j<i;j++) 25 { 26 if(m[i][j]+j<n && dp[i][j] && m[i][j]) 27 dp[i][m[i][j]+j]+=dp[i][j]; 28 if(m[i][j]+i<n && dp[i][j] && m[i][j]) 29 dp[m[i][j]+i][j]+=dp[i][j]; 30 } 31 for(j=0;j<=i;j++) 32 { 33 if(m[j][i]+i<n && dp[j][i] && m[j][i]) 34 dp[j][m[j][i]+i]+=dp[j][i]; 35 if(m[j][i]+j<n && dp[j][i] && m[j][i]) 36 dp[m[j][i]+j][i]+=dp[j][i]; 37 } 38 } 39 printf("%I64d\n",dp[n-1][n-1]); 40 } 41 return 0; 42 }