【问题背景】
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. Pycharm初始创建项目和环境搭建(解决aconda库文件引入不全等问题)

    1.新建工程 1.选择新建一个Pure Python项目,新建项目路径可以在Location处选择. 2.Project Interpreter部分是选择新建项目所依赖的python库,第一个选项会在 ...

  2. 13、git

    安装Git 网上有很多Git安装教程,如果需要图形界面,windows下建议使用TortoiseGit,linux建议使用Git GUI或者GITK.(windows下载exe安装包,linux可以使 ...

  3. 2019 第三届强网杯线上赛部分web复现

    0x00前言 周末打了强网杯,队伍只做得出来6道签到题,web有三道我仔细研究了但是没有最终做出来,赛后有在群里看到其他师傅提供了writeup和环境复现的docker环境,于是跟着学习一波并记录下来 ...

  4. Windows 使用之那些你还不知道操作

    作者:你未读 整理:君未读 关于使用 win 系统的基本普及. 建议更换 win10 系统 可能很多朋友看到这个建议,心里很不爽,还很不服气,别急,且看官方给出的信息. 也就是说在 2019 年你完全 ...

  5. 数学 HDOJ 5301 Buildings

    题目传送门 /* 题意:n*m列的矩阵,删除一个格子x,y.用矩形来填充矩阵.且矩形至少有一边是在矩阵的边缘上. 求满足条件的矩形填充方式中面积最大的矩形,要使得该最大矩形的面积最小. 分析:任何矩形 ...

  6. 设置VMWare虚拟机使拷贝虚拟机后固定原有的IP地址

    VMWare中已经安装并设置好的虚拟机在拷贝给别人后,再次打开该虚拟机时原有自动获取的IP地址将会变化,那么原有根据该IP地址进行的设置均将失效,还需要重新设置,比较麻烦,经过百度查询原来可以将虚拟机 ...

  7. sql 获取当前季度期间

    select year(getdate())*10000+((month(getdate())/3)*3+1)*100 + 1 --季度第一天 select year(getdate())*10000 ...

  8. 设置Echarts鼠标悬浮样式

    在option下 tooltip内添加以下代码: (本文在后台进行传值 也就是其中的viewstate[]) tooltip: { show: true, trigger: 'axis', //sho ...

  9. [ USACO 2010 FEB ] Slowing Down

    \(\\\) \(Description\) 给出一棵 \(N\) 个点的树和 \(N\) 头牛,每头牛都要去往一个节点,且每头牛去往的点一定互不相同. 现在按顺序让每一头牛去往自己要去的节点,定义一 ...

  10. python做一个数独小游戏

    最近看了下python的一些知识,在这里记载一下. 1.首先是安装,在官网下载最新的版本3.6,安装的时候要注意在下面勾选上ADD TO PATH,安装的时候会自动写入到环境变量里面,如果没有勾选,可 ...