zoukankan      html  css  js  c++  java
  • 【XSY2576】【2017国家集训队】换教室(k叉树+DP)

    (Description)

    对于刚上大学的牛牛来说,他面临的第一个问题是如何根据实际情况申请合适的课程。

    在可以选择的课程中,有 (2n) 节课程安排在 (n) 个时间段上。在第 (i(1≤i≤n))个时间段上,两节内容相同的课程同时在不同的地点进行,其中,牛牛预先被安排在教室 (c_{i}) 上课,而另一节课程在教室 (d_{i}) 进行。

    在不提交任何申请的情况下,学生们需要按时间段的顺序依次完成所有的 (n) 节安排好的课程。如果学生想更换第 (i) 节课程的教室,则需要提出申请。若申请通过,学生就可以在第 (i) 个时间段去教室 (d_{i}) 上课,否则仍然在教室 (c_{i}) 上课。

    由于更换教室的需求太多,申请不一定能获得通过。通过计算,牛牛发现申请更换第 (i) 节课程的教室时,申请被通过的概率是一个已知的实数 (k_{i}),并且对于不同课程的申请,被通过的概率是互相独立的。

    学校规定,所有的申请只能在学期开始前一次性提交,并且每个人只能选择至多 (m) 节课程进行申请。这意味着牛牛必须一次性决定是否申请更换每节课的教室,而不能根据某些课程的申请结果来决定其他课程是否申请;牛牛可以申请自己最希望更换教室的 (m) 门课程,也可以不用完这 (m) 个申请的机会,甚至可以一门课程都不申请。


    (真正的题目才刚刚开始,上面的都是浮云)

    因为不同的课程可能会被安排在不同的教室进行,所以牛牛需要利用课间时间从一间教室赶到另一间教室。某天,当牛牛上完课来到下一间教室时,发现教室里空无一人,黑板上用白粉笔写着(N)个数字(0)(M)个数字(1),旁边贴着一个纸条,纸条上写着另一个整数(K)

    牛牛观察了一会儿,发现(K−1)竟然整除(N+M−1。)于是,好奇的牛牛想知道,如果称“在黑板上随机选择(K)个数擦掉,并把这(K)个数的平均数作为一个新的数写在黑板上”为一次操作,在他一直重复操作直到黑板上只剩一个数后,这个数有多少种可能的取值。显然,在这个过程中,黑板上的每个数都是有理数,牛牛是大学生,学过关于分数的知识,所以你不用关心他怎么如何把一个有理数写在黑板上。请你能帮助他统计这个数值,由于该数值过大,你只需要求出它对(10^9+7)取模的值就行了。


    (Input)

    输入第一行包含三个整数(N,M,K)


    (Output)

    输出一个整数,表示黑板上最后的数字可能的取值数量对(10^9+7)取模的值。


    (Sample Input 1)

    2 2 2

    (Sample Input 2)

    3 4 3

    (Sample Input 3)

    150 150 14


    (Sample Output 1)

    5

    (Sample Output 2)

    9

    (Sample Output 3)

    937426930


    (HINT)

    在第一个样例中,(5)个可能的取值分别是(frac{1}{4})(frac{3}{8})(frac{1}{2})(frac{5}{8})(frac{3}{4})。其中,(frac{3}{8})可以通过以下方式得到:

    1. 擦去(0)(1),写上(frac{1}{2})
    2. 擦去(frac{1}{2})(1),写上(frac{3}{4})
    3. 擦去(0)(frac{3}{4}),写上(frac{3}{8})

    数据范围:

    (1≤N,M≤2000,)
    (2≤K≤2000,)
    (K−1)整除(N+M−1)

    存在10分的子任务,满足(1≤N,M,K≤10。)
    存在30分的子任务(独立于上一个子任务),满足(K=2。)


    吐槽

    有没有看到标题和体面很激动的小盆友,没错,我跟你们一样:这不就是(2016)(tg)的原题吗?!!!

    但这次终于见识到一句话入主题的精髓了

    那个改题面的人,站出来,保证不盘死你

    TMD之前的题面跟题目有什么关系啊啊


    思路

    按照习惯,看到小学生最擅长的数数题,并且需要取模,我们首先考虑(dp)

    我们观察每次取(k)个数的平均数,是不是很像一棵(k)叉树?!

    于是我们考虑一棵(k)叉树,它的叶子节点为(0)(1),每个非叶子节点的值就是它的儿子的平均值

    于是我们可以得到:这棵(k)叉树有(n+m)个叶子节点,(n)(0)(m)(1)

    (n)(0)叶子节点的深度分别为(d0_{i})(m)(1)叶子节点的深度分别为(d1_{i})

    那么我们容易得到根节点的值就为(sum k^{-d1_{i}})

    我们考虑,当全部叶子节点的值都为(1)时,那么根节点的值就为(1)

    于是,我们可以得到

    (sum k^{-d1_{i}}+sum k^{-d0_{i}}=1)

    现在,我们所要求的东西就转换成了:

    有多少个(x)可以写成(sum k^{-d1_{i}})的形式,且(1-x)可以写成(sum k^{-d0_{i}})的形式(虽然我但代码里求的是(1-x)的个数,但都一样)

    我们发现这些(sum)很烦人,于是我们将(x)表示成一个(k)进制小数 (0.a_{1}a_{2}a_{3}...a_{len}),这个小数的长度为(len)

    因为这小数部分都是由叶子节点为(1)的值构成的,于是(x)的每位小数的和为(sum_{i=1}^{len}a_{i}=m),当然,这是在没有进位之前的情况。一旦在第(p)位进位,那么(a_{p}-=1,a_{p+1}+=k),令(val=sum_{i=1}^{len}a_{i})
    所以可以得到 (valequiv m(mod) (k+1))

    我们再来看(1-x),同理,(1-x)的长度也一定是(len),并且它的位数和可以表示为((len-1)(k-1)+k-val =len(k-1)-val+1),易得(len(k-1)-val+1)需要满足(<=n)

    我们的结论已经推完啦,接下来就是(dp)

    我们设(dp[i][j])表示到小数点后第(i)位,之前的位数和为(j)的方案数

    又因为小数不能有后缀(0),所以我们要加一个状态(k)表示是否为(0)

    我们在(dp)时可以考虑用前缀和(sum)优化

    (p.s:)记得开(long) (long)


    代码:

    #include<bits/stdc++.h>
    using namespace std;
    const long long N=2010,mod=1e9+7;
    long long sum[N];
    long long f[N<<1][N][2];
    long long n,m,k;
    int main()
    {
    	scanf("%lld %lld %lld",&n,&m,&k);
    	f[0][0][0]=1;
    	long long ans=0ll;
    	for(long long i=1;i<=max(n,m)*2;i++)
    	{
    		sum[0]=(f[i-1][0][0]+f[i-1][0][1])%mod;
    		for(long long j=1;j<=n;j++)
    			sum[j]=(sum[j-1]+(f[i-1][j][0]+f[i-1][j][1])%mod)%mod;
    		for(long long j=0;j<=n;j++)
    		{
    			f[i][j][0]=(sum[j]-sum[j-1])%mod;
    			if(j)
    			{
    				if(j>=k)f[i][j][1]=(sum[j-1]-sum[j-k]+mod)%mod;
    				else f[i][j][1]=(sum[j-1]+mod)%mod;
    			}
    		}
    		for(long long j=0;j<=n;j++)
    		{
    			if(j%(k-1)==n%(k-1)&&(i*(k-1)-j+1)%(k-1)==m%(k-1)&&i*(k-1)-j+1<=m)ans=(ans+f[i][j][1])%mod;
    		}
    	}
    	printf("%lld",ans);
    	return 0;
    }
    
  • 相关阅读:
    Redis详解(三)- redis的六大数据类型详细用法
    Redis详解(二)- redis的配置文件介绍
    《OR Talk NO.11 | 清能互联赖晓文:电力系统中的运筹优化应用》
    《OR Talk NO.10 | 浙江大学徐金明:分布式优化算法何时能在性能上与集中式算法相媲美?》
    《OR Talk NO.9 | 深圳大学龚元浩:比几何流快一万倍的曲率滤波算法》
    《OR Talk NO.4 | Attain.ai 创始人李玉喜:强化学习遇见组合优化》
    《OR Talk NO.3 | 滴滴 AI Labs 秦志伟:深度强化学习在网约che交易市场中的应用》
    《OR Talk NO.2 | 胡武华博士:运筹优化理论在物流行业中的应用实践》
    《KDD 2018 | Conventional Tutorials》
    《OR Talk NO.13 | MIT 博士与你分享电商供应链算法实战心得》
  • 原文地址:https://www.cnblogs.com/ShuraEye/p/11519366.html
Copyright © 2011-2022 走看看