Sereja is interested in intervals of numbers, so he has prepared a problem about intervals for you. An interval of numbers is a pair of integers [l, r](1 ≤ l ≤ r ≤ m). Interval [l1, r1] belongs to interval [l2, r2] if the following condition is met: l2 ≤ l1 ≤ r1 ≤ r2.
Sereja wants to write out a sequence of n intervals [l1, r1], [l2, r2], ..., [ln, rn] on a piece of paper. At that, no interval in the sequence can belong to some other interval of the sequence. Also, Sereja loves number x very much and he wants some (at least one) interval in the sequence to have li = x. Sereja wonders, how many distinct ways to write such intervals are there?
Help Sereja and find the required number of ways modulo 1000000007(109 + 7).
Two ways are considered distinct if there is such j(1 ≤ j ≤ n), that the j-th intervals in two corresponding sequences are not equal.
Input
The first line contains integers n, m, x(1 ≤ n·m ≤ 100000, 1 ≤ x ≤ m) — the number of segments in the sequence, the constraints on the numbers in segments and Sereja's favourite number.
Output
In a single line print the answer modulo 1000000007(109 + 7).
1 1 1
1
3 5 1
240
2 3 3
6
题意:给出一个区间,在这个区间内选n个L和R值,使得这n个L,R不能存在包含关系,问一共有多少种方法。
sl: 可以这么搞,设当前区间的长度为L,左节点有a个,右节点有b个,dp[L][a][b] 代表解的个数。
有4种转移。
dp[k][i+1][j]+=dp[k-1][i][j]; 以第k个节点为左节点。
dp[k][i+1][j+1] 以第k个节点为左节点也为右节点。
当当前位置处于x时不能将当前节点发给右节点,因为已经和上面的重复。
另外可以用滚动数组降去k那一维。
最后乘上n的全排列,对应数对的顺序。
ps:感觉这道题目好精妙的感觉。
2 #include<cstdio>
3 #include<algorithm>
4 using namespace std;
5 typedef long long LL;
6 const int MOD = 1e9+7;
7 const int MAX = 500;
8 int dp[2][MAX][MAX];
9 int main()
10 {
11 int n,m,x,next;
12 while(scanf("%d %d %d",&n,&m,&x)==3)
13 {
14 memset(dp,0,sizeof(dp));
15 dp[0][0][0]=1;
16 next=0;
17 if(n>m) printf("0 ");
18 else
19 {
20 for(int k=1;k<=m;k++)
21 {
22 next=next^1;
23 for(int i=0;i<=n;i++) for(int j=0;j<=n;j++)
24 dp[next][i][j]=0;
25 for(int i=0;i<=n;i++) for(int j=0;j<=i;j++)
26 {
27 dp[next][i+1][j]=(dp[next][i+1][j]+dp[next^1][i][j])%MOD;
28 dp[next][i+1][j+1]=(dp[next][i+1][j+1]+dp[next^1][i][j])%MOD;
29 if(k!=x)
30 {
31 dp[next][i][j+1]=(dp[next][i][j+1]+dp[next^1][i][j])%MOD;
32 dp[next][i][j]=(dp[next][i][j]+dp[next^1][i][j])%MOD;
33 }
34 }
35 }
36 LL ans=dp[next][n][n]%MOD;
37 for(int i=1;i<=n;i++) ans=(ans*i)%MOD;
38 printf("%I64d ",ans);
39 }
40 }
41 return 0;
42 }