标签:false 不包含 round c++ -- 多少 enc turn temp
题目链接:Lucky Subsequence
题意:只含有数字4和7的为幸运数字,对于一个长为 n 的序列,问有多少个长度为 k 的子序列(可以不用连续)中不包含两个相同的幸运数字,非幸运数字可以出现任意多次。
题解:因为序列中的数字小于等于 10^9 ,所以最多会有 2^10=1024 个不同的幸运数字,记录每一个幸运数字的个数。然后用 dp[i][j] 表示前 i 个幸运数字中共取 j 个的方法数,状态转移方程为 dp[i][j]=dp[i-1][j]+dp[i-1][j-1]×num[i],其中 num[i] 为第 i 个幸运数字出现的次数。最后的答案即为 Σdp[tot][j]×C(sum, k-j),sum为非幸运数字个数
#include <bits/stdc++.h> using namespace std; typedef long long LL; const LL mod=1e9+7; LL n,k,cnt,tot; LL a[100005],b[100005],num[100005],fac[100005],dp[100005]; LL pow_mod(LL a,LL n){ LL res=1,t=a; while(n){ if(n&1) res=(res*t)%mod; t=(t*t)%mod; n/=2; } return res; } LL inv(LL x){ return pow_mod(x,mod-2); } bool lucky(LL x){ while(x){ if(x%10!=4&&x%10!=7) return false; x/=10; } return true; } LL C(LL x,LL y){ if(y==0) return 1; if(x<y) return 0; LL res=(fac[x]*inv(fac[y]))%mod; res=(res*inv(fac[x-y]))%mod; return res; } int main(){ fac[0]=1; for(LL i=1;i<=100000;i++) fac[i]=(fac[i-1]*i)%mod; scanf("%lld%lld",&n,&k); for(LL i=1;i<=n;i++){ scanf("%lld",&a[i]); if(lucky(a[i])) b[++cnt]=a[i]; } sort(b+1,b+1+cnt); LL sum=0; dp[0]=1; for(LL i=1;i<=cnt;i++){ sum++; if(b[i]!=b[i+1]||i==cnt){ tot++; for(LL j=tot;j>=1;j--){ dp[j]=(dp[j]+dp[j-1]*sum%mod)%mod; } sum=0; } } LL ans=0; for(LL i=0;i<=k;i++){ LL temp=dp[i]*C(n-cnt,k-i)%mod; ans=(ans+temp)%mod; } printf("%lld\n",ans); return 0; }
Codeforces Round #104 (Div. 1) C Lucky Subsequence
标签:false 不包含 round c++ -- 多少 enc turn temp
原文地址:https://www.cnblogs.com/N-Psong/p/10263407.html