列表

详情


NC53482. 鸽天的放鸽序列

描述

擅长放鸽子的鸽天要确定自己的放鸽序列。放鸽序列是一个长度为n的01序列,表示接下来n天的是否放鸽。众所周知,鸽天是很喜欢鸽的,所以它想得到放鸽天数最多的序列并计数。
放鸽序列有一个奇怪的要求,由于这个要求太奇怪了,所以接下来是一句话题意:
定义一个长为n的01序列的权值为,求有多少个长为n的01序列满足有恰好k个1,且权值最大。
答案对取模。

输入描述

输入一行两个数n()、k()。

输出描述

输出一个数,表示答案。

示例1

输入:

5 3

输出:

3

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

Python3(3.5.2) 解法, 执行用时: 260ms, 内存消耗: 3556K, 提交时间: 2019-10-18 20:00:06

n, k = map(int, input().split())
MOD = 10 ** 9 + 7


def pow(x, y, MOD):
    ans = 1
    tmp = x
    while y:
        if y & 1:
            ans = (ans * tmp) % MOD
        tmp = (tmp * tmp) % MOD
        y >>= 1
    return ans


def fact(x, MOD):
    ans = 1
    for i in range(2, x + 1):
        ans = (ans * i) % MOD
    return ans

n, k = n - k, (k + 1) // 2
if k == 0:
    print(1)
    exit()
print((fact(n + k - 1, MOD) * pow(fact(k - 1, MOD), MOD - 2, MOD) * pow(fact(n, MOD), MOD - 2, MOD)) % MOD)
        
        

C++11(clang++ 3.9) 解法, 执行用时: 7ms, 内存消耗: 396K, 提交时间: 2019-10-23 19:51:38

#include<iostream>
using namespace std;
const int mod =1e9+7;
const int maxn=100010;
typedef long long ll;
ll n,k;

ll pow(ll a, ll b)
{
	ll res=1;
	while(b!=0)
	{
		if(b&1) res=res*a%mod;
		a=a*a%mod;
		b>>=1;
	}
	return res;
}


int main()
{
	cin>>n>>k;
	if(k%2==0) 
	{
		n--;
		k--;
	}
	n--;k--;
	ll x=k/2,m=n-k/2,ans=1,base=1;
	//排列组合 C(x,n+x)
	for(ll i=1;i<=x;i++)
	{
		ans=ans*(m-i+1)%mod;
		base=base*i%mod;
	}
	cout<<ans*pow(base,mod-2)%mod;
	
}

C++14(g++5.4) 解法, 执行用时: 13ms, 内存消耗: 408K, 提交时间: 2019-10-29 23:57:29

#include<iostream>
using namespace std;
int mod =1e9+7;
typedef long long ll;
ll n,k;
ll pow(ll a, ll b) {
	ll res=1;
	while(b!=0) {
		if(b&1) res=res*a%mod;
		a=a*a%mod;
		b>>=1;
	}
	return res;
}
int main() {
	cin>>n>>k;
	if(k%2==0) {
		n--,k--;
	}
	n--,k--;
	ll x=k/2,m=n-k/2,ans=1,base=1;
	for(ll i=1; i<=x; i++) {
		ans=ans*(m-i+1)%mod;
		base=base*i%mod;
	}
	cout<<ans*pow(base,mod-2)%mod;
}

上一题