zoukankan      html  css  js  c++  java
  • 牛客挑战赛33 B-鸽天的放鸽序列

    也许更好的阅读体验

    (mathcal{Description})

    定义一个长为(n)(01)序列(A_1, A_2, dots, A_n)​的权值为(sum_{i=1}^n ((sum_{j=1}^i A_j) mod 2)),求有多少个长为(n)(01)序列满足有恰好(k)(1),且权值最大。
    答案对(10^9+7)取模。

    (mathcal{Solution})

    显然的两个贪心

    • 最开始是(1)最优
    • 除最开始的(1)外,之后出现(1)两个两个出现最优

    这样得到的一个序列的权值最大,其在大部分情况下是(1),只有(frac{k}{2})个是(0)
    如果有偶数个(1),那么就放一个(1)在最后,这样(0)只会出现这一次
    方案数便考虑这些(0)出现的位置
    即在一堆(1)后的空格内插入(frac{k}{2})(0)
    用组合数直接算即可

    (mathcal{Code})

    /*******************************
    Author:Morning_Glory
    LANG:C++
    Created Time:2019年10月18日 星期五 19时01分41秒
    *******************************/
    #include <iostream>
    #include <fstream>
    using namespace std;
    const int maxn = 1000006;
    const int lim = 1000000;
    const int mod = 1000000007;
    int n,k,ans;
    int fac[maxn],ifac[maxn],inv[maxn];
    int C (int n,int m){	return 1ll*fac[n]*ifac[n-m]%mod*ifac[m]%mod;}
    //{{{init
    void init ()
    {
    	fac[0]=ifac[0]=inv[1]=1;
    	for (int i=2;i<=lim;++i)	inv[i]=(-1ll*mod/i*inv[mod%i]%mod+mod)%mod;
    	for (int i=1;i<=lim;++i)	fac[i]=1ll*fac[i-1]*i%mod,ifac[i]=1ll*ifac[i-1]*inv[i]%mod;
    }
    //}}}
    int main()
    {
    	init();
    	cin>>n>>k;
    	if (!k)	return printf("1
    "),0;
    	--k,--n;
    	if (k&1)	--k,--n;
    	printf("%d
    ",C(n-k/2,k/2));
    	return 0;
    }
    
    

    如有哪里讲得不是很明白或是有错误,欢迎指正
    如您喜欢的话不妨点个赞收藏一下吧

  • 相关阅读:
    v4l2程序实例
    uboot的readme导读
    基于Linux的v4l2视频架构驱动编写
    V4L2
    Uboot优美代码赏析1:目录结构和malkefile分析
    查找 mysql 配置文件 my.cnf
    thinkphp中array_diff运行无效 Invalid opcode 153/1/8
    thinkphp后端开发ajax接口开发测试
    Thinkphp getLastSql函数用法
    web日志分析的重要性
  • 原文地址:https://www.cnblogs.com/Morning-Glory/p/11708523.html
Copyright © 2011-2022 走看看