zoukankan      html  css  js  c++  java
  • 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 ");
    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 } 


  • 相关阅读:
    Linux学习之网络基础
    C# 随笔
    最牛B的编码套路
    c++ Primer 第七章不熟悉知识点总结
    oracle求表的倒数二行数据
    c++ Primer 第六章不熟悉知识点总结
    c++ Primer 第五章不熟悉知识点总结
    c++ Primer 第四章不熟悉知识点总结
    c++ Primer 第三章不熟悉知识点总结
    骑驴找马
  • 原文地址:https://www.cnblogs.com/acvc/p/3653209.html
Copyright © 2011-2022 走看看