1 条题解
-
0
题意
有 条竖线,每条线上有 个高度。从 出发,每次遇到横线时都选择经过它,并且不存在两条端点重合的横线,一条横线的两端点必须在同一高度,一条横线连接的需要是相邻的两条竖线。求从 到 的图的方案数。
思路
考虑 ,我们可以用 表示从 到 的方案数。
在此之前,我们需要先求一个东西,我们定义 为放到第 个位置不放边的方案数,定义 为放到第 个位置放边的方案数。不难想到:
不难看出, 可以由 , 和 到达,即一个点上面三个点。
首先,假如是要直接由上面的点移下来,就需要要求上面那个点左边和右边都没有边,所以可以推出:
$$dp_{i,j} \gets dp_{i-1,j} \times f_{j-1,0} \times f_{m-j,0}$$接下来,如果是由左上的点推出,就需要要求上面那个点左边有边,而右边都没有边,所以可以推出:
$$dp_{i,j} \gets dp_{i-1,j-1} \times f_{j-1,1} \times f_{m-j,0}$$从右上的点推出的也同理。
$$dp_{i,j} \gets dp_{i-1,j+1} \times f_{j-1,0} \times f_{m-j,1}$$Code
#include<bits/stdc++.h> #define int long long using namespace std; const int mod=1000000007; int n,m,k; int f[105][2],dp[105][105]; signed main(){ scanf("%lld%lld%lld",&n,&m,&k); f[0][0]=1; for(int i=1;i<=m;i++){ f[i][0]=(f[i-1][0]+f[i-1][1])%mod; f[i][1]=f[i-1][0]; } dp[0][1]=1; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++){ dp[i][j]=(dp[i][j]+((dp[i-1][j]*((f[j-1][0]*f[m-j][0])%mod)%mod)%mod))%mod; dp[i][j]=(dp[i][j]+((dp[i-1][j-1]*((f[j-1][1]*f[m-j][0])%mod)%mod)%mod))%mod; dp[i][j]=(dp[i][j]+((dp[i-1][j+1]*((f[j-1][0]*f[m-j][1])%mod)%mod)%mod))%mod; } printf("%lld\n",dp[n][k]); return 0; }
- 1
信息
- ID
- 11607
- 时间
- 2000ms
- 内存
- 1024MiB
- 难度
- 10
- 标签
- 递交数
- 22
- 已通过
- 1
- 上传者