题解-Roman and Numbers
题解-Roman and Numbers
前置知识:
数位 \(\texttt{dp}\) </>
给定 \(n\) 和 \(m\),求将 \(n\) 的各位数字重新排列(不允许有前导 \(0\)),求可以构造几个能被 \(m\) 整除。
数据范围:\(1\le n\le 10^{18}\),\(1\le m\le 100\)。
用数位 \(\texttt{dp}\) 代码又短时间又优又好理解,为什么没人玩呢?
把 \(n\) 的各位数字拿出来排序一下,然后把每个数有没有用过状压。
for(;n;n/=10) d.pb(n%10);
sort(d.begin(),d.end()),len=d.size();
选数字的时候只允许用相同数字中第一个没用过的。
\(\texttt{Dfs}\) 中:
- \(w\):要找从右往左第几位。
- \(st\):当前数字使用状态。
- \(sum\):左 \(len-w\) 位数字形成的数 \(\bmod m\) 的余数。
il lng Dfs(re int w,re int st,re int sum){
if(!w) return sum==0;//判断被 m 整除
if(~f[st][sum]) return f[st][sum];
re lng res=0;
for(re int i=0;i<len;i++)
if(!((1<<i)&st)&&(i==0||d[i]!=d[i-1]||((1<<(i-1))&st))) //*
res+=Dfs(w-1,st|(1<<i),(sum*10+d[i])%m);
return f[st][sum]=res; //记忆化,记录答案
}
其中 \(*\) 处的判断:
- 该数字未用过。
- 该数字前的相同数字都用过。
以保证使用顺序,防止重复统计。
关于 \(f\) 记忆化数组:
现在是 \(f_{st,sum}\),本来应该是 \(f_{w,st,sum}\)。这里就讲讲 \(f_{w,st,sum}\) 记忆化的缺点:
- \(1\le w\le 18\),\(1\le st\le 2^{18}\),\(1\le sum<m\le 100\),必然 \(\color{#117}{\texttt{MLE}}\)。
- \(st\) 中 \(1\) 的数量 \(cnt\) 必然满足 \(cnt=len-w\),所以只记录 \(st\) 不会重合答案。
时间复杂度 \(\Theta(2^{len}m)\)。
Code
#include <bits/stdc++.h>
using namespace std;
//&Start
#define re register
#define il inline
#define mk make_pair
#define pb push_back
#define db double
#define lng long long
#define fi first
#define se second
#define inf 0x3f3f3f3f
//&Data
const int W=18,M=100;
int m,len;
lng n,f[1<<W|7][M|7];
vector<int> d;
//&Digitdp
il void Pre(){memset(f,-1,sizeof f);}
il lng Dfs(re int w,re int st,re int sum){
if(!w) return sum==0;
if(~f[st][sum]) return f[st][sum];
re lng res=0;
for(re int i=0;i<len;i++)
if(!((1<<i)&st)&&(i==0||d[i]!=d[i-1]||((1<<(i-1))&st)))
res+=Dfs(w-1,st|(1<<i),(sum*10+d[i])%m);
return f[st][sum]=res;
}
il lng DP(){
for(;n;n/=10) d.pb(n%10);
sort(d.begin(),d.end()),len=d.size();
re lng res=0;
for(re int i=0;i<len;i++)
if(d[i]&&(i==0||d[i]!=d[i-1])) // 这里也要判断!这是最容易错的地方
res+=Dfs(len-1,1<<i,d[i]%m);
return res;
}
//&Main
int main(){
scanf("%lld%d",&n,&m),Pre();
printf("%lld\n",DP());
return 0;
}
祝大家学习愉快!
题解-Roman and Numbers的更多相关文章
- 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 ...
- [LeetCode 题解]: Add Two Numbers
You are given two linked lists representing two non-negative numbers. The digits are stored in rever ...
- [LeetCode 题解]: Roman to Interger
前言 [LeetCode 题解]系列传送门: http://www.cnblogs.com/double-win/category/573499.html 1.题目描述 Given a ro ...
- CF401D Roman and Numbers 状压DP
CF401D 题意翻译 将n(n<=10^18)的各位数字重新排列(不允许有前导零) 求 可以构造几个mod m等于0的数字 题目描述 Roman is a young mathematicia ...
- leetcode 题解 Add Two Numbers(两个单链表求和)
题目: You are given two linked lists representing two non-negative numbers. The digits are stored in r ...
- Codeforces 401D Roman and Numbers
题目大意 Description 给定一个数 N(N<1018) , 求有多少个经过 N 重组的数是 M(M≤100) 的倍数. 注意: ①重组不能有前导零; ②重组的数相同, 则只能算一个数. ...
- LeetCode题解——Roman to Integer
题目: 将罗马数字转换为整数. 解法: 可以参考上一篇数字转换为罗马数字的规则. 代码: class Solution { public: int sym2int(char sym) //罗马数字字符 ...
随机推荐
- kafka数据一致性(HW只能保证副本之间的数据一致性,并不能保证数据不丢失ack或者不重复。)
数据一致性问题:消费一致性和存储一致性 例如:一个leader 写入 10条数据,2个follower(都在ISR中),F1.F2都有可能被选为Leader,例如选F2 .后面Leader又活了.可能 ...
- TIME_WAIT状态存在的原因
TIME_WAIT状态存在有两个理由: 1.可靠地实现TCP全双工连接的中断 2.允许老的重复分节在网络中消失 第一个理由:如果客户端的ACK丢失了,服务器将会重新发送它的最终的那个FIN,因此客户端 ...
- mysql中delete from t1 where id = 10加锁状况叙述
在Next_Key Lock算法中,不仅仅锁定住所找到的索引,而且还锁定住这些索引覆盖的范围.因此在这个范围内的插入都是不允许的.这样就避免了在这个范围内插入数据导致的幻读问题. delete fro ...
- 【python爬虫】用requests库模拟登陆人人网
说明:以前是selenium登陆取cookie的方法比较复杂,改用这个 """ 用requests库模拟登陆人人网 """ import r ...
- [LeetCode题解]141. 环形链表 | 快慢指针
题目描述 给定一个链表,判断链表中是否有环. 如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环. 为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的 ...
- 我要进大厂之大数据ZooKeeper知识点(2)
01 我们一起学大数据 接下来是大数据ZooKeeper的比较偏架构的部分,会有一点难度,老刘也花了好长时间理解和背下来,希望对想学大数据的同学有帮助,也特别希望能够得到大佬的批评和指点. 02 知识 ...
- sql bypass waf fuzz python
从freebuf copy过来的,先保存,有空再改 #encoding=utf-8 import requests url = "http://127.0.0.1/index.php?id= ...
- ACCESS渗透测试
access-getshell 直接写shell # 创建临时表 create table test(a varchar(255)); # 插入一句话木马 insert into test(a) va ...
- 算法学习笔记:Kosaraju算法
Kosaraju算法一看这个名字很奇怪就可以猜到它也是一个根据人名起的算法,它的发明人是S. Rao Kosaraju,这是一个在图论当中非常著名的算法,可以用来拆分有向图当中的强连通分量. 背景知识 ...
- 下载器Folx专业版有没有iTunes整合功能
对于使用Mac系统的用户来说,相信对iTunes都不陌生.Folx专业版提供的iTunes整合功能,能将下载的音频.电影等文件自动同步到iTunes. 该功能将会有助于用户的音频.视频整合,对于喜欢听 ...