【问题背景】
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. centos 7 配置php

    对于我们的目的而言,安装 Apache 只需要在 CentOS 命令终端敲入这条命令就行了: $ sudo yum install httpd $ sudo systemctl enable http ...

  2. 类似QQ消息左滑删除的Demo

    最近在网上学到一篇类似QQ消息左滑删除的demo,完善了下代码,感觉还不错,特此分享一波: CustomSwipeListView.java 是个继承自ListView的类,里面调用了自定义View ...

  3. Android 性能优化(15)网络优化( 11)Manipulating Broadcast Receivers On Demand

    Manipulating Broadcast Receivers On Demand This lesson teaches you to Toggle and Cascade State Chang ...

  4. Win7上安装Oracle数据库

    由于ORACLE并没有FOR WIN7的版本,必须下载for vista_w2k8这个版本,将oralce 10G的安装镜像解压到硬盘,然后修改安装目录下的rehost.xml和oraparam.in ...

  5. 红黑树与AVL(平衡二叉树)的区别

    关于红黑树和AVL树,来自网络: 1 好处 及 用途 红黑树 并不追求“完全平衡 ”——它只要求部分地达到平衡要求,降低了对旋转的要求,从而提高了性能. 红黑树能够以 O(log2  n)  的时间复 ...

  6. 304 Range Sum Query 2D - Immutable 二维区域和检索 - 不可变

    给定一个二维矩阵,计算其子矩形范围内元素的总和,该子矩阵的左上角为 (row1, col1) ,右下角为 (row2, col2). 上图子矩阵左上角 (row1, col1) = (2, 1) ,右 ...

  7. [译]The multi Interface

    The multi Interfacemulti接口 The easy interface as described in detail in this document is a synchrono ...

  8. 向listview控件中添加数据库数据

    //连接字符串 string str = "Data Source=.;Initial Catalog=mu;User ID=sa;Password=111"; //创建数据库连接 ...

  9. Myeclipse2014安装&破解激活

    市场上很多JavaWeb的IDE比如Idea(听说用好开发效率会很高),eclipse(插件丰富还免费),但是对于初学者还是为了提高学习的效率(Myeclipse创建web项目的时候可以自动生成一些配 ...

  10. 启用adb wifi无线调试功能(无需root)

    1  工具 电脑.手机 2  前提 电脑和手机出于同一网段 3  步骤 以管理员方式打开cmd,运行 adb tcpip 5555(执行tcpip调试模式) adb connect  192.168. ...