题意&&思路:
每一步只能向下走或者向右走,然后所构成的路径不能重叠,所以就尽可能的往下面走,然后给第二条更大的空间
解法1:dfs+剪枝
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<stdlib.h>
using namespace std;
const int N=15;
char s[N];
bool a[N][N],vis[N][N];
int n;
bool dfs1(int y,int x)//先向下走,再向右走
{
if(y==n&&x==n) return 1;
if(y+1<=n&&a[y+1][x])
{
if(dfs1(y+1,x)) {vis[y][x]=1; return 1;}
}
if(x+1<=n&&a[y][x+1])
{
if(dfs1(y,x+1)) {vis[y][x]=1; return 1;}
}
return 0;
}
bool dfs2(int y,int x)//先向右走,再向左走
{
if(y==n&&x==n) return 1;
if(x+1<=n&&a[y][x+1]&&!vis[y][x+1])
{
if(dfs2(y,x+1)) return 1;
}
if(y+1<=n&&a[y+1][x]&&!vis[y+1][x])
{
if(dfs2(y+1,x)) return 1;
}
return 0;
}
int main()
{
int test;
cin>>test;
while(test--)
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%s",s+1);//我觉得这种读入方式很棒
for(int j=1;j<=n;j++)
if(s[j]=='.')a[i][j]=1;
else a[i][j]=0;
}
memset(vis,0,sizeof(vis));
int ans=0;
if(!a[1][1])//如果一开始就不能走的话,那就是0
//if本身就有先后选择关系
{
printf("0\n");
continue;
}
if(dfs1(1,1))//这里表明了是先看向下走,再向右走
{
ans++;
if(dfs2(1,1))ans++;
}
printf("%d\n",ans);
}
return 0;
}
推dp方程,用LGV定理
//#pragma GCC optimize(3,"Ofast","inline")
#include <bits/stdc++.h>
#define ll long long
using namespace std;
int n,dp[1010][1010];
char s[1010][1010];
ll ac(int a,int b,int c,int d)
{
memset(dp,0,sizeof(dp));
for(int i=a; i<=c; i++)
{
for(int j=b; j<=d; j++)
{
if(s[i][j]=='.')
{
if(i==a && j==b) dp[i][j]=1;
else dp[i][j] = dp[i-1][j] + dp[i][j-1];
}
}
}
return dp[c][d];
}
int main()
{
int T;
cin>>T;
while(T--)
{
scanf("%d",&n);
for(int i=1; i<=n; i++) cin>>s[i]+1;
if(s[1][1]=='#'||s[n][n] == '#') {
printf("0\n");
continue;
}
ll t1 = ac(1, 2, n-1, n);
ll t2 = ac(2, 1, n, n-1);
ll t3 = ac(1, 2, n, n-1);
ll t4 = ac(2, 1, n-1, n);
if(t1*t2-t3*t4) printf("2\n");
else {
int flag = ac(1,1,n,n);
if(flag) printf("1\n");
else printf("0\n");
}
}
return 0;
}
呐,这里扩展一下LGV
LGV引理可以用于在有向无环便(DAG)上求解不相交路径方案数问题
非降路径之和
暂时是我不能敲出来的,以后再来练练