CodeForces 367E Sereja and Intervals

CodeForces 3 67E

 

Description

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 nmx(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).

 

 

 

Input
1 1 1

 

Output
1
Input
3 5 1
Output
240
Input
2 3 3
Output
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:感觉这道题目好精妙的感觉。

 

 1 #include<cstring>
 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\n");
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\n",ans);
39         }
40     }
41     return 0;

42 } 

 

 

 

 


posted @ 2014-04-08 23:23  acvc  阅读(469)  评论(2编辑  收藏  举报