zoukankan      html  css  js  c++  java
  • CF101B Buses

    CF101B Buses

    洛谷传送门

    题意翻译

    Gerald家住在离学校很远的地方,他每天上学都要做公交车。 Gerald家被标为0号车站,学校被标为n号车站,再Gerald家和学校之间还有n-1个车站。 在Gerald家和学校之间,有m辆公交车。第i辆公交车从第si个车站驶往第ti个车站。Gerald可以在第si个车站到第(ti-1)个车站之间任意一个车站上这辆公交车,但是只能在第ti个车站下车。 Gerald不能在两个车站中间走动,也不能沿返回的路线走。 问Gerald有多少种不同的从家到学校的方法。输出答案模1e9+7。 标准输入 两个数字n和m,表示站台的个数和公交车的个数 接下来m行每行两个数字,为si和ti 标准输出 输出一个数字,即本题的答案。


    题解:

    计数类题想DP。

    首先想:状态可以设成(dp[i])表示到车站(i)下车有多少种方式。答案是(dp[n])。但是发现(n)很大,而且不太好转移。所以开始思考:到车站(i)下车,只能是终点在(i)的车次。既然(m)的范围可以,又有这个性质,能不能直接用车次代替位置来维护呢?

    可以:设状态为(dp[i])表示第(i)趟车(当然要在(t[i])下车)的方案数,最终答案是所有(t[i]=n)(dp[i])的和。转移也非常好想:能在(t[i])下车,一定会在(s[i]-t[i])这段路上上车,所以只需要枚举有哪些车次的终点在这段路上,这些车都可以转移到当前状态。

    那就麻烦了,怎么找到这些转移的车次呢?

    我们可以考虑对其按右端点进行排序,这样,转移而来的那些车次一定在当前车次之前。那么,就可以通过二分查找来找到这个东西。

    代码:

    #include<cstdio>
    #include<vector>
    #include<algorithm>
    using namespace std;
    const int maxm=1e5+5;
    const int mod=1e9+7;
    int n,m,ans;
    vector<pair<int,int> >e;
    vector<int> f;
    int dp[maxm],sum[maxm];
    int main()
    {
        scanf("%d%d",&n,&m);
        e.push_back(make_pair(0,0));
        f.push_back(0);
        for(int i=1;i<=m;i++)
        {
            int s,t;
            scanf("%d%d",&s,&t);
            e.push_back(make_pair(t,s));
            f.push_back(t);
        }
        sort(e.begin(),e.end());
        sort(f.begin(),f.end());
        for(int i=1;i<=m;i++)
        {
            int x=e[i].second,y=e[i].first;//x,y是当前路线的起终点
            if(!x)
                dp[i]=1;
            int s=lower_bound(f.begin(),f.end(),x)-f.begin();
            int t=lower_bound(f.begin(),f.end(),y)-f.begin();
            dp[i]=(dp[i]+sum[t]-sum[s]+mod)%mod;
            sum[i+1]=(sum[i]+dp[i])%mod;
        }
        for(int i=1;i<=m;i++)
            if(e[i].first==n)
                ans=(ans+dp[i])%mod;
        printf("%d
    ",ans);
        return 0;
    }
    
  • 相关阅读:
    python 面向对象编程
    用python写个快排
    函数(参数,作用域,返回函数,匿名函数,偏函数)
    SpringBoot学习4:springboot整合listener
    SpringBoot学习1:创建第一个SpringBoot项目
    SpringBoot学习2:springboot整合servlet
    SpringBoot学习3:springboot整合filter
    使用FreeMarker导出word文档(支持导出图片)
    MySQL中实现递归查询
    MySQL中find_in_set()函数的使用
  • 原文地址:https://www.cnblogs.com/fusiwei/p/14057168.html
Copyright © 2011-2022 走看看