zoukankan      html  css  js  c++  java
  • UOJ#204 【APIO2016】Boat

    Time Limit: 70 Sec  Memory Limit: 256 MB
    Submit: 559  Solved: 248

    Description

    在首尔城中,汉江横贯东西。在汉江的北岸,从西向东星星点点地分布着个划艇学校,编号依次为到。每个学校都
    拥有若干艘划艇。同一所学校的所有划艇颜色相同,不同的学校的划艇颜色互不相同。颜色相同的划艇被认为是一
    样的。每个学校可以选择派出一些划艇参加节日的庆典,也可以选择不派出任何划艇参加。如果编号为的学校选择
    派出划艇参加庆典,那么,派出的划艇数量可以在Ai至Bi之间任意选择(Ai<=Bi)。值得注意的是,编号为i的学
    校如果选择派出划艇参加庆典,那么它派出的划艇数量必须大于任意一所编号小于它的学校派出的划艇数量。输入
    所有学校的Ai、Bi的值,求出参加庆典的划艇有多少种可能的情况,必须有至少一艘划艇参加庆典。两种情况不同
    当且仅当有参加庆典的某种颜色的划艇数量不同

    Input

     第一行包括一个整数N,表示学校的数量。接下来N行,每行包括两个正整数,用来描述一所学校。其中第行包括的

    两个正整数分别表示Ai,Bi(1<=Ai<=Bi<=10^9),N<=500

    Output

     输出一行,一个整数,表示所有可能的派出划艇的方案数除以1,000,000,007得到的余数

    Sample Input

    2
    1 2
    2 3

    Sample Output

    7

    HINT

    Source

    动态规划

    看着题解懵X一个多小时,我这么弱已经没救了吧

    枚举数量显然无力,我们得考虑将整段区间一起处理,于是先将区间离散化

    将派船看作在限定区间里选一个数,设f[i][j][k]表示当前枚举到第i个学校,最大船数在第j段,这段里选了k个数的方案数。

    $ f[i][j][k]=f[i-1][j][k]+f[i-1][j][k-1]* frac {C(len[j],k)}{C(len[j],k-1)} $

    特殊处理 $ f[i][j][1]=f[i-1][j][1] + (sum_{a=1}^{j-1}  sum_{k=0}^{i-1} f[i-1][a][k] )*len[j] $

    第一维可以滚动优化掉

    第一个式子的组合数,约分一下变成了(len-k+1)/k ,预处理500以内的逆元即可。

    第二个式子用前缀和优化。

    然后大概就能过了

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #define LL long long
     6 using namespace std;
     7 const int mod=1e9+7;
     8 const int mxn=1105;
     9 int read(){
    10     int x=0,f=1;char ch=getchar();
    11     while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    12     while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
    13     return x*f;
    14 }
    15 int inv[mxn];
    16 void init(){
    17     inv[0]=inv[1]=1;
    18     for(int i=2;i<mxn;i++){
    19         inv[i]= ((-mod/i)*(LL)inv[mod%i]%mod+mod)%mod;
    20     }
    21     return;
    22 }
    23 int n;
    24 int c[mxn][mxn];
    25 struct seg{
    26     int L,R;
    27 }a[mxn];
    28 int pos[mxn],sz=0,len[mxn];
    29 int f[mxn][mxn],g[mxn];
    30 int num[mxn];
    31 int main(){
    32 //    freopen("boat.in","r",stdin);
    33 //    freopen("boat.out","w",stdout);
    34     int i,j;
    35     n=read();
    36     init();
    37     for(i=1;i<=n;i++){
    38         a[i].L=read()-1;a[i].R=read();
    39         pos[++sz]=a[i].L;pos[++sz]=a[i].R;
    40     }
    41     sort(pos+1,pos+sz+1);
    42     sz=unique(pos+1,pos+sz+1)-pos-1;
    43 //    for(i=1;i<=sz;i++)printf("%d",pos[i]);
    44     for(i=1;i<=n;i++){
    45         a[i].L=lower_bound(pos+1,pos+sz+1,a[i].L)-pos;
    46         a[i].R=lower_bound(pos+1,pos+sz+1,a[i].R)-pos;
    47     }
    48     for(i=1;i<=sz;i++)len[i]=pos[i]-pos[i-1];
    49     f[0][1]=1;
    50     for(i=1;i<=sz;i++)g[i]=1;
    51     for(i=1;i<=n;i++){
    52         for(j=a[i].L+1;j<=a[i].R;j++){
    53             num[j]++;
    54             for(int k=num[j];k>1;k--)
    55                 f[j][k]=((LL)f[j][k]+(LL)f[j][k-1]*(len[j]-k+1)%mod*(LL)inv[k])%mod;
    56             f[j][1]=((LL)f[j][1]+(LL)g[j-1]*len[j]%mod)%mod;
    57         }
    58         for(j=a[i].L+1;j<=sz;j++){
    59             g[j]=g[j-1];
    60             for(int k=num[j];k;k--){
    61                 g[j]=((LL)g[j]+f[j][k])%mod;
    62             }
    63         }
    64     }
    65     g[sz]--;if(g[sz]<=0)g[sz]+=mod;
    66     printf("%d
    ",g[sz]);
    67     return 0;
    68 }
  • 相关阅读:
    oracle 巡检脚本(自动化) 规格严格
    应用版日常linux系统巡检shell脚本 规格严格
    linux系统巡检脚本 规格严格
    超级详细RPM 规格严格
    项目管理纪实一:需求调研日志
    其实你不懂程序员
    Silverlight同步(Synchronous)调用WCF服务
    GeoServer地图开发解决方案(一):环境搭建篇
    新年新起点荣获2011年度Silverlight方向Microsoft® MVP奖
    工作中发现 VC 通过 Flex 访问 FusionChart for FLEX 当VC端的驱动数据串过长时,会出现 No Data to Display错误
  • 原文地址:https://www.cnblogs.com/SilverNebula/p/6830015.html
Copyright © 2011-2022 走看看