Codeforces Round #202 (Div. 1): D. Turtles(Lindström–Gessel–Viennot lemma定理+DP)
阿新 • • 發佈:2018-11-23
題意:
給你一個n*m的地圖,"#"是障礙,"."是路,不能走出邊界,問從(1,1)到(n,m)選出兩條不相交最短路徑的方案數是多少(其中起點和終點相同不算相交)
思路:
知道Lindström–Gessel–Viennot lemma定理就是水題了
對於一個無邊權有向無環圖,給出n個起點和對應的n個終點,這n條不相交路徑的方案數為
行列式的值
其中e(a, b)為圖上a點到b點的方案個數
對於這題
行列式大小為2
且a1 = (1, 2);a2 = (2, 1);b1 = (n-1, m);b2 = (n, m-1);
直接套就可以了
#include<stdio.h> #include<string.h> #include<algorithm> #include<map> #include<string> #include<math.h> #include<queue> #include<stack> #include<iostream> using namespace std; #define LL long long #define mod 1000000007 char str[3005][3005]; int dp1[3005][3005], dp2[3005][3005]; int main(void) { int n, m, i, j; scanf("%d%d", &n, &m); for(i=1;i<=n;i++) scanf("%s", str[i]+1); if(str[1][2]=='#' || str[2][1]=='#') printf("0\n"); else { dp1[1][2] = dp2[2][1] = 1; for(i=1;i<=n;i++) { for(j=1;j<=m;j++) { if(i+j<=3 || str[i][j]!='.') continue; dp1[i][j] = (dp1[i][j-1]+dp1[i-1][j])%mod; dp2[i][j] = (dp2[i][j-1]+dp2[i-1][j])%mod; } } //printf("%d %d %d %d\n", dp1[n-1][m], dp1[n][m-1], dp2[n-1][m], dp2[n][m-1]); printf("%lld\n", (((LL)dp1[n-1][m]*dp2[n][m-1]-(LL)dp1[n][m-1]*dp2[n-1][m])%mod+mod)%mod); } return 0; }