1. 程式人生 > >UVa 825【簡單dp,遞推】

UVa 825【簡單dp,遞推】

space 遞推 log 題目 logs .org str eof scan

UVa 825

題意:給定一個網格圖(街道圖),其中有一些交叉路口點不能走。問從西北角走到東南角最短走法有多少種。(好像沒看到給數據範圍。、。)

簡單的遞推吧,當然也就是最簡單的動歸了。顯然最短路長度就是row+col。求種數就從開始往後推。

由於第一行第一列也有可能是障礙點,所以初始化時要註意這一點,或者幹脆就只初始化f[0][1]=1。i、j都從1開始遞推到更方便。還有題目輸入輸出比較坑。輸入我用的是sstream和stream,方便很多,要不還要按照字符串輸入再手動轉化成數字。輸出讓每組隔一行,但最後一組沒有,用while(T)控制。

 1 #include<iostream>
 2
#include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<string> 6 #include<sstream> 7 using namespace std; 8 const int maxn = 4006; 9 int g[maxn][maxn], f[maxn][maxn]; 10 int row, col, res; 11 12 int main() 13 { 14 int T; 15 scanf("%d", &T);
16 while (T--) 17 { 18 memset(g, 0, sizeof(g)); 19 scanf("%d%d", &row, &col); 20 char cc = getchar(); 21 string line; 22 int tmp; 23 for (int i = 1; i <= row; i++) 24 { 25 getline(cin, line); 26 stringstream ss(line);
27 int cn = 0; 28 while (ss >> tmp) { 29 cn++; 30 if (cn>1) 31 g[i][tmp] = 1; 32 } 33 } 34 memset(f, 0, sizeof(f)); 35 f[0][1] = 1; 36 for (int i = 1; i <= row; i++) { 37 for (int j = 1; j <= col; j++) { 38 if (g[i][j]) continue; 39 f[i][j] = f[i - 1][j] + f[i][j - 1]; 40 } 41 } 42 printf("%d\n", f[row][col]); 43 if (T) printf("\n"); 44 } 45 return 0; 46 }

UVa 825【簡單dp,遞推】