lucky

排列组合 

#include <iostream>
#include <cstdio>
#include <map>
#define LL long long
using namespace std;
int read(bool &f)
{
	f=1;
	int x=0;
	char c=getchar();
	while(c<'0'||c>'9')  c=getchar();
	while(c>='0'&&c<='9')
	{
		if(c!='4'&&c!='7')  f=0;
		x=x*10+c-'0';
		c=getchar();
	}
	return x;
}
const int M=2000,mod=1e9+7,N=1e5+5;
LL n,m,k,a[M],b[M],num,a1,dp[M][M],ans,o[N];
bool f;
map <int,int> mp;
LL pow(LL a,LL p)
{
	LL s=1;
	while(p)
	{
		if(p&1)  s=s*a%mod;
		a=a*a%mod;
		p>>=1;
	}
	return s;
}
LL c(LL n,LL m)
{
	if(m==n||m==0)  return 1;
	return o[n]*pow(o[m],mod-2)%mod*pow(o[n-m],mod-2)%mod;
}
int main()
{
	freopen("lucky.in","r",stdin);
	freopen("lucky.out","w",stdout);
	
	n=read(f);  k=read(f);
	
	o[0]=1;
	for(int i=1;i<=n;i++)  o[i]=o[i-1]*i%mod;
	
	for(int i=1;i<=n;i++)
	{
		a1=read(f);
		if(f)
		{
			if(!mp[a1])
			{
				mp[a1]=++num;
				a[num]=a1;
				b[num]=1;
			}
			else  b[mp[a1]]++;
	    }
	    else  m++;
	}
	
	for(int i=0;i<=num;i++)  dp[i][0]=1;
	for(int i=1;i<=num;i++)
	  for(int j=1;j<=i;j++)
	  	dp[i][j]=(dp[i-1][j]+dp[i-1][j-1]*b[i]%mod)%mod;
	
	for(int i=max(k-m,(LL)0);i<=k;i++)
	  ans=(ans+dp[num][i]*c(m,k-i)%mod)%mod;
	cout<<ans;
	
	fclose(stdin);  fclose(stdout);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_42192786/article/details/89920346