CF401D Roman and Numbers
题意:
将n(n<=10^18)的各位数字重新排列(不允许有前导零) 求 可以构造几个mod m等于0的数字
分析:
状态压缩
状态:
设f[s][k]表示对于选择数字组合的s来说,%m等于k的排列数量。
第一维大小:2^18 第二维大小:100
阶段:
对于s的选择的枚举。s直接从1枚举到1<<(cnt+1) 这样到了s(n)时,所有能转移到s(n)的状态都已经处理完毕。不会有后效性。
由于对于1~n的所有排列,可以考虑是从中选择任意的n-1个数的所有排列,再在最末尾选上剩余的一个数。 所以之后的s(n)所能转移到的最优解,都是与s(n)有关系的(都是通过在s(n)末尾接上一个数转移的),所以满足最优子结构性质。
转移:
对于给定的s,它的18位二进制表示中的每一位是0或者是1表示这一位上的数选择或者不选择。 我们将i从0循环到cnt,(cnt=n的位数-1)想要枚举的是s的每一位1,即枚举出来这个s所选的所有的数的位置,也就知道了所选择的数。
再枚举一下余数j,这样,可以写出这样的状态转移方程:
f[s][(j x 10+w[i])%m]+=f[s^(1<<i)][j]
意义是:每一位的选择都是通过这一位不选择的剩下状态,再把这一位放在末尾组成状态s转移的。
设之前的数为X,X=km+j;
选择了w[i]之后,X=10km+10j+w[i]; 余数就变成了:(10j+w[i])%m
然而有一个缺陷。。。
在于对于有重复数字时,会将一个状态转移从“其实是同一个组合”转移多遍,
举例:n=221 111会从101 转移一次,还会从011转移一次。然而这两个组合其实都是2、1,所以会算重。
所以可以在最后的时候进行多重集合的处理。 也可以每次枚举的时候,判断这一位的值是否之前已经处理过了。
if(vis[w[i]]) continue;
代码:
#include<bits/stdc++.h> #define ll long long const int maxs=(1<<18)+5; const int maxn=110; using namespace std; int cnt=-1,w[20],m; ll f[maxs][maxn],n; bool vis[10]; int main() {for(cin>>n>>m;n;n/=10)w[++cnt]=n%10;f[0][0]=1;for(int s=1;s<1<<cnt+1;s++){ memset(vis,0,sizeof vis);//注意清空for(int i=0;i<=cnt;i++){if(s==(1<<i)&&!w[i]) break;//去掉前导零if(!(s&(1<<i))||vis[w[i]]) continue;//判断是否选择了这一位,并且跳过已经处理过删去w[i]之后转移的情况。vis[w[i]]=1;//标记处理过这个数了。for(int j=0;j<m;j++)f[s][(j*10+w[i])%m]=(f[s][(j*10+w[i])%m]+f[s^(1<<i)][j]); } }cout<<f[(1<<cnt+1)-1][0];//f[11..1][0]return 0; }
转载于:https://www.cnblogs.com/Miracevin/p/9031579.html
CF401D Roman and Numbers相关推荐
- codeforces #235 D. Roman and Numbers 题解
转载请注明:http://blog.csdn.net/jiangshibiao/article/details/23100595 [原题] D. Roman and Numbers time limi ...
- codeforces 401D. Roman and Numbers 数位dp
题目链接 给出一个<1e18的数, 求将他的各个位的数字交换后, 能整除m的数的个数. 用状态压缩记录哪个位置的数字已经被使用了, 具体看代码. 1 #include<bits/stdc+ ...
- 动态规划总结与题目分类
源博客链接:http://blog.csdn.net/cc_again/article/details/25866971 动态规划一直是ACM竞赛中的重点,同时又是难点,因为该算法时间效率高,代码量少 ...
- 『ACM-算法-动态规划』初识DP动态规划算法
一.多阶段决策过程的最优化问题 在现实生活中,有类活 动的过程,由于 它的特殊性,可将过程分成若干个互相阶段.在它的每一阶段都需要作出决策,从而使整个过程达到最好的活动效果.当阶段决策的选取不是任意确 ...
- (转)dp动态规划分类详解
dp动态规划分类详解 转自:http://blog.csdn.NET/cc_again/article/details/25866971 动态规划一直是ACM竞赛中的重点,同时又是难点,因为该算法时间 ...
- 《动态规划》— 动态规划分类
动态规划(英语:Dynamic programming,DP)是一种在数学.计算机科学和经济学中使用的,通过把原问题分解为相对简单的子问题的方式求解复杂问题的方法. 动态规划常常适用于有重叠子问题和最 ...
- 转:动态规划题目分类
https://blog.csdn.net/cc_again/article/details/25866971 一.简单基础dp 这类dp主要是一些状态比较容易表示,转移方程比较好想,问题比较基本常见 ...
- 【DP专辑】ACM动态规划总结
转载请注明出处,谢谢. http://blog.csdn.net/cc_again?viewmode=list ---------- Accagain 2014年5月15日 ...
- ACM比赛经验、刷题记录及模板库总结(更新中)
前言 本文所提及的部分题目代码,可以在我的Github上找到 第一部分 经验分享及感受 第二部分 刷题记录 一.基础算法&程序语言 //strlen()函数的复杂度是O(n)要小心 //截取字 ...
最新文章
- 设置centos6.5虚拟机时间同步
- TF之BN:BN算法对多层中的每层神经网络加快学习QuadraticFunction_InputData+Histogram+BN的Error_curve
- 关于MySQL的慢日志分析工具
- 常用公有云接入——华为
- 从天而降的文字,文字掉落效果
- 【QtDesigner 开发笔记】在PyCharm中配置、使用方法、信号与槽、菜单、Tab Widget、子窗口
- plupload与springmvc分段上传视频
- CSS 内边距 和尺寸(收藏)
- 新出行超级产业链之交通工具变革(网址导航)
- 2019清华大学、中山大学、中传自主招生笔试面试真题
- 永久免费的数据库防火墙(堡垒机)
- iOS安全逆向之旅---逆向基本知识概要介绍
- java--吸血鬼数的判断
- 介绍一款LaTeX编辑器——LyX
- 在 Python 中打印换行符——打印一个新行
- 第十四章 涅焚心经的强大之处
- 【机器学习实战】朴素贝叶斯(连续型/离散型)
- wampserver局域网可以访问在线状态下的本地网站
- 计算机技术考长沙理工大学难不难,长沙理工大学难考吗?长沙理工大学值得上吗?...
- 豆瓣9.7,这些舍不得看完的神剧,看一集少一集啊!