码迷,mamicode.com
首页 > 其他好文 > 详细

CodeForces - 367E:Sereja and Intervals(组合数&&DP)

时间:2018-12-20 15:41:50      阅读:220      评论:0      收藏:0      [点我收藏+]

标签:contain   correct   efi   single   include   examples   pair   output   condition   

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

Examples
Input
1 1 1
Output
1
Input
3 5 1
Output
240
Input
2 3 3
Output
6
Note

In third example next sequences will be correct: {[1, 1], [3, 3]}, {[1, 2], [3, 3]}, {[2, 2], [3, 3]}, {[3, 3], [1, 1]}, {[3, 3], [2, 2]}, {[3, 3], [1, 2]}.

题意:给定长度为M的数轴,让你选择N个带编号的线段,使得没有线段有包含关系。 给定X,让你至少选择了一个左端点为X的线段。

思路:N<=M;  所以N<sqrt(N*M)<=330; 没有包含关系,那么线段A的左端点大于B的左端点,那么A的右端点也一定大于B的右端点。所以我们可以自己去匹配。只保存当点左端点和右端点个数即可。

用dp[i][j][x]表示前x个点选择了i个左端点,j个右端点,不难得到方程。由于x可能有点大,我们用滚动数组。

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=330;
const int Mod=1e9+7;
int dp[maxn][maxn][2];
int main()
{
    int N,M,X;
    scanf("%d%d%d",&N,&M,&X);
    if(N>M) return puts("0"),0;
    dp[0][0][0]=1;
    rep(k,1,M){//位置
      rep(i,0,min(N,M)){ //左括号
        rep(j,0,i){ //右括号
            int p=k&1;
            if(k==X){
                dp[i][j][p]=0;
                if(i>j) (dp[i][j][p]+=dp[i-1][j][p^1])%=Mod; //
                if(i&&j) (dp[i][j][p]+=dp[i-1][j-1][p^1])%=Mod;//左+右
            }
            else {
                dp[i][j][p]=dp[i][j][p^1]; //不放
                if(i>j) (dp[i][j][p]+=dp[i-1][j][p^1])%=Mod; //
                if(i&&j) (dp[i][j][p]+=dp[i-1][j-1][p^1])%=Mod;//左+右
                if(j) (dp[i][j][p]+=dp[i][j-1][p^1])%=Mod;//
            }
        }
      }
    }
    rep(i,1,N) dp[N][N][M&1]=1LL*dp[N][N][M&1]*i%Mod;
    printf("%d\n",dp[N][N][M&1]);
    return 0;
}

 

CodeForces - 367E:Sereja and Intervals(组合数&&DP)

标签:contain   correct   efi   single   include   examples   pair   output   condition   

原文地址:https://www.cnblogs.com/hua-dong/p/10149481.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!