BZOJ 1616 [Usaco2008 Mar]Cow Travelling游荡的奶牛:dp【网格型】
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1616
题意:
有一个n*m的网格。
'.'表示平坦的草地,'*'表示挡路的树(不能走)。
有一只奶牛,第0秒时在(r1,c1),第t秒时在(r1,c2)。
它每一秒钟都会向上下左右任一方向走一格,不会停留不动。
问你在这t秒钟内,奶牛可能的移动路径数。
题解:
表示状态:
dp[i][j][k]:表示在第k秒,走到了位置(i,j)时的方案数。
找出答案:
ans = dp[r2][c2][t]
t秒时到达终点
如何转移:
dp[nx][ny][k+1] += dp[i][j][k]
(nx,ny)为(i,j)的上下左右四个位置。
边界条件:
dp[r1][c1][0] = 1
others = 0
初始时只有一种方案。
AC Code:
1 #include <iostream> 2 #include <stdio.h> 3 #include <string.h> 4 #define MAX_N 105 5 #define MAX_T 20 6 7 using namespace std; 8 9 const int dx[]={-1,1,0,0}; 10 const int dy[]={0,0,-1,1}; 11 12 int n,m,t; 13 int r1,c1; 14 int r2,c2; 15 int dp[MAX_N][MAX_N][MAX_T]; 16 char a[MAX_N][MAX_N]; 17 18 void read() 19 { 20 cin>>n>>m>>t; 21 for(int i=1;i<=n;i++) 22 { 23 for(int j=1;j<=m;j++) 24 { 25 cin>>a[i][j]; 26 } 27 } 28 cin>>r1>>c1>>r2>>c2; 29 } 30 31 inline bool is_legal(int x,int y) 32 { 33 return x>0 && x<=n && y>0 && y<=m && a[x][y]!='*'; 34 } 35 36 void solve() 37 { 38 memset(dp,0,sizeof(dp)); 39 dp[r1][c1][0]=1; 40 for(int k=0;k<t;k++) 41 { 42 for(int i=1;i<=n;i++) 43 { 44 for(int j=1;j<=m;j++) 45 { 46 for(int p=0;p<4;p++) 47 { 48 int x=i+dx[p]; 49 int y=j+dy[p]; 50 if(is_legal(x,y)) 51 { 52 dp[x][y][k+1]+=dp[i][j][k]; 53 } 54 } 55 } 56 } 57 } 58 } 59 60 void print() 61 { 62 cout<<dp[r2][c2][t]<<endl; 63 } 64 65 int main() 66 { 67 read(); 68 solve(); 69 print(); 70 }