//模拟+递推,感觉这种题不能称之为动态规划,只能叫递推因为每个点只调用了一次,不存在所谓的转移 //题意是从起点到终点,有多少种不同的走法,图中有些路有障碍 //注意到规模是M*N <= 1000000,所以直接模拟就得了,数组嘛不能开成二维的会MLE //把二维的坐标转化成1维的,这样就开的下了,数组的每个位存放的是十字路口的点,记录走到当前点有多少种不同的走法 //X,Y这两个BOOL型数组,记录的是当前这条路是否被阻碍了,每个点左下方都对应着2条路,分别用X,Y来存放,这样对应关系会清晰些 //至于哪条路被堵,这个得自己画个图琢磨琢磨,一开始我搞错了,WA了1次 //最坏情况是1000000*2+1..所以得开到100W,这样还真蛋疼,初始化的时候慢了好多 #include<iostream> #include<cstdio> #include<cstring> using namespace std; int M,N,B; int x,y,dx,dy; bool X[2000000],Y[2000000]; long long A[2000000]; int trans(int x,int y)//二维到一维的映射关系 { return x*(N+1)+y; } int main() { //freopen("in.txt","r",stdin); while(scanf("%d%d",&M,&N) && M*N != 0) { memset(X,0,sizeof(X)); memset(Y,0,sizeof(Y)); memset(A,0,sizeof(A)); scanf("%d",&B); while(B--) { scanf("%d%d%d%d",&x,&y,&dx,&dy); for(int i = x;i < x+dx;++i) { for(int j = y;j < y+dy;++j) { if(y+dy-1 > j) Y[trans(i,j)] = 1; if(x+dx-1 > i) X[trans(i,j)] = 1; } } } for(int i = 1;i <= N;++i) A[i] = 1; for(int i = 1;i <= M;++i) A[i*(N+1)] = 1;//初始化 for(int i = 1;i <= M;++i) { for(int j = 1;j <= N;++j) { if(X[trans(i,j)] && Y[trans(i,j)]) continue; A[trans(i,j)] = (Y[trans(i,j)] ? 0 : A[trans(i-1,j)]) + (X[trans(i,j)] ? 0 : A[trans(i,j-1)]); } } printf("%lld/n",A[trans(M,N)]); } }