题意:给你一个n*m的图,给你b个矩形(在图中,不能通过),只能向上和右走,问左下角到右上角有多少种走法。
思路:经典的dp,dp[i][j]=max(dp[i-1][j],dp[i][j-1]),但是n*m实在太大,不可能直接开这么大的数组,想一下只需要两行的数据就能求出最优解,所以用滚动数组。
dp[k][j]=max(dp[1-k][j],dp[k][j-1]),k代表当前行,1-k代表前一行。
#include <iostream> #include<cstdio> #include<cstring> using namespace std; #define LL long long LL many[2][1000010]; int m,n,b,building[1010][4]; inline int inside(int x,int y){ int i; for(i=0;i<b;i++) if(x>=building[i][0]&&x<building[i][0]+building[i][2]-1&&y>=building[i][1] &&y<building[i][1]+building[i][3]-1) return 1; return 0; } int main(int argc, char** argv) { int i,j,kk; while(scanf("%d%d",&m,&n)!=EOF,n*m){ scanf("%d",&b); for(i=0;i<=n;i++){ many[0][i]=1; many[1][i]=0; } for(i=0;i<b;i++) for(j=0;j<4;j++) scanf("%d",&building[i][j]); kk=1; for(i=1;i<=m;i++){ many[kk][0]=1; for(j=1;j<=n;j++) if(inside(i,j)) many[kk][j]=0; else many[kk][j]=many[kk][j-1]+many[1-kk][j]; kk=1-kk; } printf("%lld\n",many[1-kk][n]); } return 0; }
soj 1033 City Road_经典dp,布布扣,bubuko.com
原文地址:http://blog.csdn.net/neng18/article/details/24888561