【问题背景】
zhx 和妹子们玩数数游戏。
【问题描述】
仅包含 4 或 7 的数被称为幸运数。
一个序列的子序列被定义为从序列中删去若干个数, 剩下的数组成的新序列。
两个子序列被定义为不同的当且仅当其中的元素在原始序列中的下标的集合不
相等。对于一个长度为 N的序列,共有 2^N个不同的子序列。(包含一个空序列)。
一个子序列被称为不幸运的, 当且仅当其中不包含两个相同的幸运数。
对于一个给定序列, 求其中长度恰好为 K 的不幸运子序列的个数, 答案 mod
10^9+7 输出。
【输入格式】
第一行两个正整数 N, K, 表示原始序列的长度和题目中的 K。
接下来一行 N 个整数 ai, 表示序列中第 i 个元素的值。
【输出格式】
仅一个数,表示不幸运子序列的个数。(mod 10^9+7)
【样例输入】
3 2
1 1 1
【样例输出】
3
【样例输入】
4 2
4 7 4 7
【样例输出】
4

【样例解释】
对于样例 1, 每个长度为 2 的子序列都是符合条件的。
对于样例 2,4个不幸运子序列元素下标分别为:{1, 2}, {3, 4}, {1, 4}, {2, 3}。
注意下标集{1, 3}对应的子序列不是“不幸运”的, 因为它包含两个相同的幸运数
4.
【数据规模与约定】

分析:好题啊!暴力做法很简单,满分做法需要具备一定的数学知识.

不幸运的数随便怎么选都行,关键是幸运的数要怎么选.可以把幸运的数提出来,用数组b保存。要选总长度为K的子序列,我们可以在b中选K1个,在不幸的数中选K2个.b中的数因为每个数只能选一个,所以可以先去重,并用一个数组cnt[i]记录第i个幸运数有多少个.注意到b中的每类数要么不选,要么就有cnt[i]种选法,一共要选K1个,很像dp,究竟能否dp呢?理论上来说是可以的,但是如果幸运数很多的话状态就表示不了.好在题目中说了ai<=10^9,大约有1000个幸运数,是完全可以dp的.

设f[i][j]表示前i类幸运数中组成长度为j的序列的方案数有多少种.b中的每类数要么不选,要么就有cnt[i]种选法,所以f[i][j] = f[i-1][j] + f[i-1][j-1] * cnt[i].K1的部分计算完了.

K2部分其实就是求若干个组合数.因为N特别大,不能用递推来求出所有的组合数,只能在需要的时候求.涉及到除法取模,所以要求逆元,又因为有很多组合数要求,所以先预处理出1到n的阶乘、逆元、逆元的阶乘就好了,最后枚举K1,K1部分的答案与K2部分的答案乘一下就可以了.

注意:K1枚举的时候K2一定不能大于不幸运数的个数.

把不同类别的东西分开处理是这道题的关键点.有很多限制的计数子问题一般都用dp,限制不多的dp和数学方法都行.

#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm> using namespace std; typedef long long ll; const int mod = 1e9 + ; ll n, a[], k, ans,m, jie[], niyuan[], nijie[], b[], cnt[], tot, tott, f[][]; void init()
{
jie[] = ;
jie[] = ;
niyuan[] = ;
nijie[] = ;
nijie[] = ; //
for (ll i = ; i <= n; i++)
{
jie[i] = (jie[i - ] * i) % mod;
niyuan[i] = (mod - mod / i) * niyuan[mod % i] % mod;
nijie[i] = (nijie[i - ] * niyuan[i]) % mod;
//printf("%lld %lld %lld %lld\n", i, jie[i], niyuan[i], nijie[i]);
}
} bool check(ll x)
{
while (x)
{
if (x % != && x % != )
return false;
x /= ;
}
return true;
} void print()
{
for (int i = ; i <= tott; i++)
for (int j = ; j <= tott; j++)
printf("%d %d %lld\n", i, j, f[i][j]);
} int main()
{
scanf("%lld%lld", &n, &k);
init();
for (ll i = ; i <= n; i++)
scanf("%lld", &a[i]);
for (ll i = ; i <= n; i++)
if (check(a[i]))
b[++tot] = a[i];
sort(b + , b + + tot);
for (int i = ; i <= tot; i++)
{
if (b[i] != b[i - ])
cnt[++tott] = ;
else
cnt[tott]++;
}
f[][] = ;
for (int i = ; i <= tott; i++)
{
f[i][] = ;
for (int j = ; j <= tott; j++)
f[i][j] = (f[i - ][j] + f[i - ][j - ] * cnt[i] % mod) % mod;
}
//print();
m = n - tot;
//printf("flag! %lld\n", tott);
for (int i = tott; i >= ; i--)
{
if (k - i > m)
break;
ll temp = jie[m] * nijie[k - i] % mod * nijie[m - k + i] % mod;
//printf("%lld %lld %lld %lld\n", temp,m,k-i,m - k + i);
ans = (ans + temp * f[tott][i] % mod) % mod;
}
printf("%lld\n", ans); return ;
}

noip模拟赛 运的更多相关文章

  1. NOIP模拟赛 by hzwer

    2015年10月04日NOIP模拟赛 by hzwer    (这是小奇=> 小奇挖矿2(mining) [题目背景] 小奇飞船的钻头开启了无限耐久+精准采集模式!这次它要将原矿运到泛光之源的矿 ...

  2. NOIP模拟赛20161022

    NOIP模拟赛2016-10-22 题目名 东风谷早苗 西行寺幽幽子 琪露诺 上白泽慧音 源文件 robot.cpp/c/pas spring.cpp/c/pas iceroad.cpp/c/pas ...

  3. contesthunter暑假NOIP模拟赛第一场题解

    contesthunter暑假NOIP模拟赛#1题解: 第一题:杯具大派送 水题.枚举A,B的公约数即可. #include <algorithm> #include <cmath& ...

  4. 大家AK杯 灰天飞雁NOIP模拟赛题解/数据/标程

    数据 http://files.cnblogs.com/htfy/data.zip 简要题解 桌球碰撞 纯模拟,注意一开始就在袋口和v=0的情况.v和坐标可以是小数.为保险起见最好用extended/ ...

  5. 队爷的讲学计划 CH Round #59 - OrzCC杯NOIP模拟赛day1

    题目:http://ch.ezoj.tk/contest/CH%20Round%20%2359%20-%20OrzCC杯NOIP模拟赛day1/队爷的讲学计划 题解:刚开始理解题意理解了好半天,然后发 ...

  6. 队爷的Au Plan CH Round #59 - OrzCC杯NOIP模拟赛day1

    题目:http://ch.ezoj.tk/contest/CH%20Round%20%2359%20-%20OrzCC杯NOIP模拟赛day1/队爷的Au%20Plan 题解:看了题之后觉得肯定是DP ...

  7. 队爷的新书 CH Round #59 - OrzCC杯NOIP模拟赛day1

    题目:http://ch.ezoj.tk/contest/CH%20Round%20%2359%20-%20OrzCC杯NOIP模拟赛day1/队爷的新书 题解:看到这题就想到了 poetize 的封 ...

  8. CH Round #58 - OrzCC杯noip模拟赛day2

    A:颜色问题 题目:http://ch.ezoj.tk/contest/CH%20Round%20%2358%20-%20OrzCC杯noip模拟赛day2/颜色问题 题解:算一下每个仆人到它的目的地 ...

  9. CH Round #52 - Thinking Bear #1 (NOIP模拟赛)

    A.拆地毯 题目:http://www.contesthunter.org/contest/CH%20Round%20%2352%20-%20Thinking%20Bear%20%231%20(NOI ...

随机推荐

  1. bzoj 4596: [Shoi2016]黑暗前的幻想乡【容斥原理+矩阵树定理】

    真是简单粗暴 把矩阵树定理的运算当成黑箱好了反正我不会 这样我们就可以在O(n^3)的时间内算出一个无向图的生成树个数了 然后题目要求每个工程队选一条路,这里可以考虑容斥原理:全选的方案数-不选工程队 ...

  2. SP1043 GSS1 - Can you answer these queries I(猫树)

    给出了序列A[1],A[2],…,A[N]. (a[i]≤15007,1≤N≤50000).查询定义如下: 查询(x,y)=max{a[i]+a[i+1]+...+a[j]:x≤i≤j≤y}. 给定M ...

  3. centos docker 安装mysql 8.0

    centos 版本  CentOS Linux release 7.5.1804 (Core) 内核版本: 3.10.0-862.el7.x86_64 下载最新版mysql docker pull m ...

  4. redis的持久化的原理介绍和实现

    redis提供了持久化功能——RDB和AOF.通俗的讲就是将内存中的数据写入硬盘中. RDB一定时间取存储文件,AOF默认每秒去存储历史命令,官方建议两种方式同时使用 一.RDB(Redis Data ...

  5. C# 文件压缩方法

    using System; using System.IO; using System.IO.Packaging; namespace Utility { public class ZipHelper ...

  6. IKanalyzer、ansj_seg、jcseg三种中文分词器的实战较量

    转自:http://lies-joker.iteye.com/blog/2173086 选手:IKanalyzer.ansj_seg.jcseg 硬件:i5-3470 3.2GHz 8GB win7 ...

  7. datagrid上面的查询按钮设置了,但是分页工具栏不显示

    原因:查询的linkbutton没有放在toolbar里. <script type="text/javascript"> $(function(){ $('#dg') ...

  8. elastic-job 的简单使用

    说明:这个是使用2.1.5版本 elastic-job是当当开源的的的定时任务,使用也是很简单的,可以解决数据量的大的时候可以分片执行,多应用节点部署时候不会重复执行. 是通过zookeeper作为控 ...

  9. CF842C Ilya And The Tree

    思路: 1. 如果根节点是0,那么可以通过一次dfs计算出所有节点的最大值. 2. 如果根节点不是0,那么其余各点的最大值一定是根节点的一个因子.首先计算出根节点的所有因子.在dfs到一个深度为d的节 ...

  10. [Android]异常3-java.lang.NoClassDefFoundError: javax.activation.DataHandler

    背景:JavaMail发送电子邮件 异常原因: 可能一>缺少DataHandler类相关jar包 可能二>有DataHandler类,DataHandler类与使用的mail.jar包不一 ...