题意:

将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相关推荐

  1. codeforces #235 D. Roman and Numbers 题解

    转载请注明:http://blog.csdn.net/jiangshibiao/article/details/23100595 [原题] D. Roman and Numbers time limi ...

  2. codeforces 401D. Roman and Numbers 数位dp

    题目链接 给出一个<1e18的数, 求将他的各个位的数字交换后, 能整除m的数的个数. 用状态压缩记录哪个位置的数字已经被使用了, 具体看代码. 1 #include<bits/stdc+ ...

  3. 动态规划总结与题目分类

    源博客链接:http://blog.csdn.net/cc_again/article/details/25866971 动态规划一直是ACM竞赛中的重点,同时又是难点,因为该算法时间效率高,代码量少 ...

  4. 『ACM-算法-动态规划』初识DP动态规划算法

    一.多阶段决策过程的最优化问题 在现实生活中,有类活 动的过程,由于 它的特殊性,可将过程分成若干个互相阶段.在它的每一阶段都需要作出决策,从而使整个过程达到最好的活动效果.当阶段决策的选取不是任意确 ...

  5. (转)dp动态规划分类详解

    dp动态规划分类详解 转自:http://blog.csdn.NET/cc_again/article/details/25866971 动态规划一直是ACM竞赛中的重点,同时又是难点,因为该算法时间 ...

  6. 《动态规划》— 动态规划分类

    动态规划(英语:Dynamic programming,DP)是一种在数学.计算机科学和经济学中使用的,通过把原问题分解为相对简单的子问题的方式求解复杂问题的方法. 动态规划常常适用于有重叠子问题和最 ...

  7. 转:动态规划题目分类

    https://blog.csdn.net/cc_again/article/details/25866971 一.简单基础dp 这类dp主要是一些状态比较容易表示,转移方程比较好想,问题比较基本常见 ...

  8. 【DP专辑】ACM动态规划总结

    转载请注明出处,谢谢.   http://blog.csdn.net/cc_again?viewmode=list          ----------  Accagain  2014年5月15日 ...

  9. ACM比赛经验、刷题记录及模板库总结(更新中)

    前言 本文所提及的部分题目代码,可以在我的Github上找到 第一部分 经验分享及感受 第二部分 刷题记录 一.基础算法&程序语言 //strlen()函数的复杂度是O(n)要小心 //截取字 ...

最新文章

  1. 设置centos6.5虚拟机时间同步
  2. TF之BN:BN算法对多层中的每层神经网络加快学习QuadraticFunction_InputData+Histogram+BN的Error_curve
  3. 关于MySQL的慢日志分析工具
  4. 常用公有云接入——华为
  5. 从天而降的文字,文字掉落效果
  6. 【QtDesigner 开发笔记】在PyCharm中配置、使用方法、信号与槽、菜单、Tab Widget、子窗口
  7. plupload与springmvc分段上传视频
  8. CSS 内边距 和尺寸(收藏)
  9. 新出行超级产业链之交通工具变革(网址导航)
  10. 2019清华大学、中山大学、中传自主招生笔试面试真题
  11. 永久免费的数据库防火墙(堡垒机)
  12. iOS安全逆向之旅---逆向基本知识概要介绍
  13. java--吸血鬼数的判断
  14. 介绍一款LaTeX编辑器——LyX
  15. 在 Python 中打印换行符——打印一个新行
  16. 第十四章 涅焚心经的强大之处
  17. 【机器学习实战】朴素贝叶斯(连续型/离散型)
  18. wampserver局域网可以访问在线状态下的本地网站
  19. 计算机技术考长沙理工大学难不难,长沙理工大学难考吗?长沙理工大学值得上吗?...
  20. 豆瓣9.7,这些舍不得看完的神剧,看一集少一集啊!

热门文章

  1. 隐藏讨厌的桌面挂载卷图标
  2. HTML开发中的一个问题
  3. 基于SSM实现绿色有机产品直营网
  4. java.sql.SQLException: Unknown system variable 'query_cache_size'
  5. java基础相关知识
  6. 快速理解Token,Cookie,Session
  7. 洛谷 1281 书的复制
  8. vim的基本快捷操作(二)——可视模式
  9. apk反编译工具-apktool
  10. 软件项目第一次Sprint评分表