CF258B

题意:

7个人在 $ [1,m] $ 区间内取数,求第一个人选的数的4和7的个数大于其他人的4和7个数总和的方案数。

解法:

要求输入的 $ m $ 可以很大,而且需要按位考虑每隔人的贡献,所以考虑数位DP。

设 $ f[i][j] $ 表示到第 $ i $ 位,有 $ j $ 个数是 $ 4 和 7 $ 的方案数,再利用dfs进行转移就行。

CODE :

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm> using namespace std; #define LL long long
const LL MOD = 1e9+7; LL final,dp[16][16],c[16];
int bit[16],l,cnt,tot,m; int work(int m, int n) {
cnt = tot = l = 0;
for (; m; m /= 10) bit[++l] = m % 10;
for (int i = l; i && tot <= n; --i) {
for(int j = 0 ; j < bit[i] ; j++)
if (j == 4 || j == 7) {
if (tot < n) cnt += dp[i - 1][n - tot - 1];
} else cnt += dp[i - 1][n - tot];
if (bit[i] == 4 || bit[i] == 7) ++tot;
}
if(tot == n) ++cnt;
if(n == 0) --cnt;
return cnt;
}
void dfs(int t, int now, int lim, LL ans) {
if (t == 6) (final += ans) %= MOD;
else {
for (int i = 0; i <= 9 && i + now < lim; ++i)
if (c[i]) {
c[i]--;
dfs(t + 1, now + i, lim, ans * (c[i] + 1) % MOD);
c[i]++;
}
}
} int main() {
scanf("%d", &m);
dp[0][0] = 1;
for(int i = 0 ; i <= 9 ; i++) {
for(int j = 0 ; j <= i ; j++) {
dp[i + 1][j + 1] += dp[i][j] * 2;
dp[i + 1][j] += dp[i][j] * 8;
}
}
for(int i = 0 ; i <= 9 ; i++) c[i] = work(m, i);
for(int i = 0 ; i <= 9 ; i++) {
if (c[i]) {
--c[i];
dfs(0, 0, i, (c[i] + 1) % MOD);
++c[i];
}
}
printf("%lld \n", final);
//system("pause");
return 0;
}

CF258B的更多相关文章

随机推荐

  1. 5-MySQL DBA笔记-开发技巧

    第5章 开发技巧 本章将介绍一些和数据库相关的开发技巧.由于开发领域很广,这里只选取部分比较常见的小技巧.5.1 存储树形数据 有时我们需要保存一些树形的数据结构,比如组织架构.话题讨论.知识管理.商 ...

  2. 自定义策略-简单实践 <一>

    1.建立   netcore  mvc 项目. 2.startup.cs 中添加服务 services.AddAuthorization(option=> { var requirements ...

  3. 【ES6 】Promise

    Promise对象定义: 用来处理异步编程 Promise对象的特点 对象的状态不受外界影响 一旦状态改变,就不会再变,任何时候都可以得到这个结果 Promise对象的状态 pending(进行中) ...

  4. python+requests模拟登陆 学校选课系统

    最近学校让我们选课,每天都有不同的课需要选....然后突发奇想试试用python爬学校选课系统的课程信息 先把自己的浏览器缓存清空,然后在登陆界面按f12 如图: 可以看到登陆时候是需要验证码的,验证 ...

  5. excel中的更新链接

    表格每次打开都提示是否更新连接 在 [  数据 -->   编辑链接  ]  中也看到了这个连接 学着网上说的查找方式,去查找路径中包含的文字,文件名中包含的名字,都定位不到这个用了链接的单元格 ...

  6. Android实习结束后的阶段性总结

    2015年4月14日即将实习结束,在过去的五六个月里,对于Android开发还是学到了很多,临走前将以前做的笔记整理一下,自己也再回顾一次.零散是必然的,也可能只是一小段代码片段,但都是曾经我在学An ...

  7. 获取impala下所有的数据库建表语句

    方法一: 现在的导出还是有缺陷的,导出的文件中还是存在其他不必要的信息 #!/bin/bash ##获取数据库 databases=$(hive -e "show databases; ex ...

  8. Linux学习笔记(一)分区

    一.硬件设备文件名 二.设备文件名 /dev/hda1(IDE硬盘接口) /dev/sda1(SCSI硬盘接口.SATA硬盘接口) 其中,a代表第1个硬盘(以此类推,b为第2个硬盘),1代表第1个分区 ...

  9. cifs

    加入cifs 能把设备的目录挂载到我们的电脑上面 mount -t cifs -o username=Everyone //192.168.23.72/cifs /cif 如果当前是everyone ...

  10. Pycharm中查看内置函数的源码

    方法1.鼠标放在函数上,Ctrl+B,看源码 方法2.将光标移动至要查看的方法处,按住ctrl 键,点击鼠标左键,即可查看该方法的源码.