Codeforces 401D Roman and Numbers
题目大意
Description
给定一个数 N(N<1018) , 求有多少个经过 N 重组的数是 M(M≤100) 的倍数.
注意: ①重组不能有前导零; ②重组的数相同, 则只能算一个数.
Input
第一行两个数 N , M .
Output
输出满足要求的数的个数.
Sample Input
223 4
Sample Output
1
题解
状压DP.
\(f[i][j]\)中, \(i\)是状态, 表示原数中哪些位已经被新数占用. 因此, 一个Naive的想法就是对于新数的每一位, 进行一次DP, 时间复杂度: \(2^{18} \times 18 \times 18\), 显然会TLE.
我们注意到, 每当我们进行一次转移, 也就是在新数中填入一位的时候, 状态\(i\)都只会变小, 因此我们从\(2^{18} - 1\)往下直接进行一次DP即可. 时间复杂度: \(2^{18} * 18\), 尚可接受.
#include <cstdio>
#include <cstring>
const int LEN = 18, M = 100;
int main()
{
#ifndef ONLINE_JUDGE
freopen("CF401D.in", "r", stdin);
#endif
static long long pw[LEN];
pw[0] = 1;
for(int i = 1; i < LEN; ++ i)
pw[i] = pw[i - 1] * 10;
long long n, m;
scanf("%lld%lld\n", &n, &m);
int len = 0;
long long tmp = n;
static int cnt[10];
for(; tmp; tmp /= 10, ++ len)
++ cnt[tmp % 10];
static long long fac[10];
for(int i = 0; i < 10; ++ i)
{
fac[i] = 1;
for(int j = 1; j <= cnt[i]; ++ j)
fac[i] *= j;
}
static long long f[1 << LEN][M];
memset(f, 0, sizeof(f));
f[(1 << len) - 1][0] = 1;
/*
for(int l = len - 1; ~ l; -- l)
for(long long i = 0; i < 1 << len; ++ i)
for(int j = 0; j < m; ++ j)
if(f[i][j])
{
for(int k = 0; k < len; ++ k)
{
if(n / pw[k] % 10 == 0 && l == len - 1)
continue;
if(i >> k & 1)
f[i ^ (1 << k)][(j + n / pw[k] % 10 * pw[l]) % m] += f[i][j];
}
f[i][j] = 0;
} */
for(int i = (1 << len) - 1; ~ i; -- i)
for(int j = 0; j < len; ++ j)
if(i >> j & 1 && (i ^ (1 << len) - 1 || n / pw[j] % 10 % 10))
for(int k = 0; k < m; ++ k)
f[i ^ (1 << j)][(k * 10 + n / pw[j] % 10) % m] += f[i][k];
long long ans = f[0][0];
for(int i = 0; i < 10; ++ i)
ans /= fac[i];
printf("%lld\n", ans);
}
Codeforces 401D Roman and Numbers的更多相关文章
- codeforces 401D. Roman and Numbers 数位dp
题目链接 给出一个<1e18的数, 求将他的各个位的数字交换后, 能整除m的数的个数. 用状态压缩记录哪个位置的数字已经被使用了, 具体看代码. #include<bits/stdc++. ...
- Codeforces Round #235 (Div. 2) D. Roman and Numbers 状压dp+数位dp
题目链接: http://codeforces.com/problemset/problem/401/D D. Roman and Numbers time limit per test4 secon ...
- Codeforces Round #235 (Div. 2) D. Roman and Numbers (数位dp、状态压缩)
D. Roman and Numbers time limit per test 4 seconds memory limit per test 512 megabytes input standar ...
- Codeforces Round #235 (Div. 2) D. Roman and Numbers(如压力dp)
Roman and Numbers time limit per test 4 seconds memory limit per test 512 megabytes input standard i ...
- [codeforces 55]D. Beautiful numbers
[codeforces 55]D. Beautiful numbers 试题描述 Volodya is an odd boy and his taste is strange as well. It ...
- 题解-Roman and Numbers
题解-Roman and Numbers 前置知识: 数位 \(\texttt{dp}\) </> \(\color{#9933cc}{\texttt{Roman and Numbers} ...
- CF401D Roman and Numbers 状压DP
CF401D 题意翻译 将n(n<=10^18)的各位数字重新排列(不允许有前导零) 求 可以构造几个mod m等于0的数字 题目描述 Roman is a young mathematicia ...
- CodeForces - 1245A Good ol' Numbers Coloring (思维)
Codeforces Round #597 (Div. 2 Consider the set of all nonnegative integers: 0,1,2,-. Given two integ ...
- CodeForces 682A Alyona and Numbers (水题)
Alyona and Numbers 题目链接: http://acm.hust.edu.cn/vjudge/contest/121333#problem/A Description After fi ...
随机推荐
- LeetCode(155) Min Stack
题目 Design a stack that supports push, pop, top, and retrieving the minimum element in constant time. ...
- nordic芯片开发——烧写方法记录
在开发nordic芯片的时候,分为存外设开发和结合softdevice开发,另外还有结合mbr的开发(这个暂时没有深究)在裸机开发的时候,sdk里面称为blank,把芯片的程序erase之后,直接下载 ...
- CRC点滴
研究了一个晚上,大致看懂了crc校验的方法.这里记录一下,因为can总线中需要用到crc校验的. 举例说明CRC校验码的求法:(此例子摘自百度百科:CRC校验码) 信息字段代码为: 1011001:对 ...
- poj 1321 排兵布阵问题 dfs算法
题意:有不规则地图,在上面放n个相同的棋子,要求摆放的时候不同行不同列.问:有多少种摆法? 思路:dfs+回溯 用一个book[]数组来表示当前列是否有放棋子 一行一行的遍历,对一行来说遍历它的列,如 ...
- JQuery根据字母检索元素并导航到指定位置
介绍:类似于实现ios通讯录中右侧字母,快速导航到联系人的效果,如图: Html代码如下,分别是字母和港星名字的排序: <input type="text" id=" ...
- Linux学习-进程管理
为什么进程管理这么重要呢? 这是因为: 首先,我们在操作系统时的各项工作其实都是经过某个 PID 来达成的 (包括你的 bash 环境), 因此,能不能进行某项工作,就与该进程的权限有关了. 再来,如 ...
- HDU 3394 双连通分量 桥 Railway
第一个答案是统计图中桥的个数 如果一个点-双连通分量中边的个数大于点的个数那么这个块中所有的边都是冲突的,累加到第二个答案中去. #include <iostream> #include ...
- 深入Python底层,谈谈内存管理机制
说到内存管理,就先说一下垃圾回收吧.垃圾回收是Python,Java等语言管理内存的一种方式,说的直白些,就是清除无用的垃圾对象.C语言及C++中,需要通过malloc来进行内存的申请,通过free而 ...
- dotnet core 运行程序注意事项
.net core 程序 debug版本无法直接运行,因为没有相关的dll,只有在进入项目文件夹那一层,执行 dotnet run 来运行,会自动链接 当前用户的个人文件夹下的 .nuget/.pac ...
- 你应该知道的.net平台下socket异步通讯(代码实例)
1,首先添加两个windows窗体项目,一个作为服务端server,一个作为客户端Client 2,然后添加服务端代码,添加命名空间,界面上添加TextBox控件 using System.Net; ...