住房及城乡建设部信息中心网站,电子技术培训机构,用台电脑做网站,wordpress 2.9problem
luogu-P5999
solution
每个点只能跳一次#xff0c;显然跳出来形成的顺序是一个排列。不难联想到最近刷的排列 dpdpdp。
然后#xff0c;我觉得难点在于怎么转化这个跳的规则#xff0c;因为现在并不确定能否按排列 dpdpdp 一样分段做。 跳的顺序形成的排列必须…problem
luogu-P5999
solution
每个点只能跳一次显然跳出来形成的顺序是一个排列。不难联想到最近刷的排列 dpdpdp。
然后我觉得难点在于怎么转化这个跳的规则因为现在并不确定能否按排列 dpdpdp 一样分段做。 跳的顺序形成的排列必须满足以下两个条件之一 排列中第 iii 个元素必须小于两边的元素。排列中第 iii 个元素必须大于两边的元素。 排列的起终点(墙)为 s,ts,ts,t。 转化后发现这是可以排列 dpdpdp 的。
我们从小到大考虑 iii。设 f(i,j):f(i,j):f(i,j): 前 iii 个数将排列分成了 jjj 段的合法方案数。 iii 不是墙。 合并两段jjj 段有 j−1j-1j−1 个空。f(i,j)←f(i−1,j1)∗jf(i,j)\leftarrow f(i-1,j1)*jf(i,j)←f(i−1,j1)∗j。 新插一段可以插在任何位置但若 sss 已过则不能插首若 ttt 已过则不能插尾。 f(i,j)←f(i−1,j−1)∗(j−(is)−(it))f(i,j)\leftarrow f(i-1,j-1)*\big(j-(is)-(it)\big)f(i,j)←f(i−1,j−1)∗(j−(is)−(it))。 iii 是墙。只能放在首尾。 单独成段。f(i,j)←f(i−1,j−1)f(i,j)\leftarrow f(i-1,j-1)f(i,j)←f(i−1,j−1)。与相邻段合并相当于延伸。f(i,j)←f(i−1,j)f(i,j)\leftarrow f(i-1,j)f(i,j)←f(i−1,j)。
时间复杂度 O(n2)O(n^2)O(n2)。
code
#include bits/stdc.h
using namespace std;
#define int long long
#define mod 1000000007
#define maxn 2005
int f[maxn][maxn];
int n, s, t;signed main() {scanf( %lld %lld %lld, n, s, t );f[1][1] 1;for( int i 2;i n;i )if( i ^ s and i ^ t )for( int j 1;j n;j )f[i][j] (f[i - 1][j - 1] * (j - (i s) - (i t) ) f[i - 1][j 1] * j) % mod;elsefor( int j 1;j n;j )f[i][j] (f[i - 1][j - 1] f[i - 1][j]) % mod; printf( %lld\n, f[n][1] );return 0;
}