【问题背景】
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. LOJ#510. 「LibreOJ NOI Round #1」北校门外的回忆(线段树)

    题面 传送门 题解 感谢\(@M\_sea\)的代码我总算看懂题解了-- 这个操作的本质就是每次把\(x\)的\(k\)进制最低位乘\(2\)并进位,根据基本同余芝士如果\(k\)是奇数那么最低位永远 ...

  2. Android 性能优化(24)*性能工具之「Traceview,dmtracedump」Profiling with Traceview and dmtracedump :记录并查看函数调用栈*

    Profiling with Traceview and dmtracedump In this document Traceview Layout         Traceview工具界面介绍 T ...

  3. linux环境mxnet 安装

    环境ubuntu 16.04 1.安装依赖项: sudo update && sudo apt-get install -y build-essential git libatlas- ...

  4. Angular JS中自定义标签 属性绑定的解释

    看到自定义标签的文档时,文档作者解释的能力实在太弱,也可能是本人太笨,一下绕不过来. 看了一个stackoverflow答案,才算明白,在此贴出翻译,以供大家参考. .csharpcode, .csh ...

  5. TypeError: slice indices must be integers or None or have an __index__ method

    由于除法/自动产生的类型是浮点型,因此出现上述错误,修正方法为,将/更改为// roi_gray_lwpCV = gray_lwpCV[y:y + h // 2, x:x + w] # 检出人脸区域后 ...

  6. Eclipse开发工具介绍

    Eclipse是一个基于Java的.开放源码的.可扩展的应用开发平台,它为编程人员提供了一流的Java集成开发环境(Integrated Development Environment,IDE).在E ...

  7. LDA算法(入门篇)

    一. LDA算法概述: 线性判别式分析(Linear Discriminant Analysis, LDA),也叫做Fisher线性判别(Fisher Linear Discriminant ,FLD ...

  8. jenkins部署遇到离线问题如何解决

    部署jenkins页面时遇到离线问题如何解决 部署jenkins遇到一个问题,然后告诉我你的jenkins已经离线,什么鬼,后来找了很多博客 后来自己终于验证成功了,也分享给大家,只需把https改为 ...

  9. 校内测之zay与银临 (day2)(只有T1)

    一些与题目无关的碎碎念 推出式子来一定要化简!!!freopen不要写错!!!特判不要瞎搞!!!! 做到以上三点能高35分qwq T1 江城唱晚 你看数据那么大,显然又是一道数学题. 这里有n个种海棠 ...

  10. 模板—splay

    #include<iostream> #include<cstdio> #define cin(x) scanf("%d",&x) using na ...