题目

[SCOI2007]排列

给一个数字串s和正整数d, 统计s有多少种不同的排列能被d整除(可以有前导0)。例如123434有90种排列能被2整除,其中末位为2的有30种,末位为4的有60种。

输入格式

输入第一行是一个整数T,表示测试数据的个数,以下每行一组s和d,中间用空格隔开。s保证只包含数字0, 1, 2, 3, 4, 5, 6, 7, 8, 9.

输出格式

每个数据仅一行,表示能被d整除的排列的个数。

样例

样例输入

7
000 1
001 1
1234567890 1
123434 2
1234 7
12345 17
12345678 29

样例输出

1
3
3628800
90
3
6
1398

数据范围与提示

在前三个例子中,排列分别有1, 3, 3628800种,它们都是1的倍数。

100%的数据满足:s的长度不超过10, 1<=d<=1000, 1<=T<=15。

思路

  • 这道题棘手的地方是如何将数转化为二进制数存储状态,所以,我们先不管他所在数位的具体数目是多少,用二进制记录状态(1代表有,0代表没有),就很明了了,再来考虑数的问题,开一个和原字符组长度相等的数组,记录相应数位的数大小,我们定义DP数组\(F[i][j]\)代表状态\(i\)下余数为\(j\)的排序个数,\(cnt[i]\)记录\(i\)出现次数(作用下文说明),用\(a[i]\)代表原字符串相应\(i-1\)位置上的数的大小;
  • 接着我们在第一层枚举状态\(i\),第二层枚举余数\(k\),在此加判断,如果\(f[i][k]\)为0,不需要进行以下操作,为0叠加无效,第三层枚举在\(i\)状态后面插入的数字\(j\),如果\(j\)位的数字没有出现,则进行转移 \(f[(i|(1<<j))][(k*10+a[j+1])%mod] += f[i][k]\),上一状态的最优借叠加上来。
  • 还有一点就是数字重复,这时候就体现\(cnt\)的作用了,记录某个数字出现的次数,这些数字相互交换位置答案一样,对于数字\(i\),出现\(cnt[i]\)次,那么有\(A^{cnt[i]}_{cnt[i]}\)重复,要用\(f[lim-1][0]\)除去,注意判零!!!(还有一种去重方法,详细见<刘某>

上代码



#include<bits/stdc++.h>
using namespace std;
const int maxn=1<<11,maxm=1000+10;
int f[maxn][maxm];//f[i][j]表示状态i余数为j的排序个数
int T,mod;
int a[maxn],cnt[maxn];//cnt记录某个数i出现的次数
char s[15];
int J[]={0,1,2,6,24,120,720,5040,40320,362880,3628800};
int main(){
scanf("%d",&T);
while(T--){
memset(cnt, 0, sizeof(cnt));//一定记得初始化
memset(f, 0, sizeof(f));
scanf("%s%d",s,&mod);
int len=strlen(s);
for(int i=0;i<len;i++){
a[i+1]=s[i]-'0';
cnt[a[i+1]]++;//记录a[i+1]出现次数
}
int lim=1<<len;//记录界限
f[0][0]=1;//初始化临界状态,0状态下余数为0的有1种情况
for(int i=0;i<lim;i++){//枚举状态
for(int k=0;k<mod;k++){//枚举余数
if(f[i][k]){//假如没有跳过
for(int j=0; j<len; j++)//枚举插入的数字
if( (i & (1<<j)) == 0 )//无交集
f[(i|(1<<j))][(k*10+a[j+1])%mod] += f[i][k];//叠加
}
}
}
int ans=f[lim-1][0];
for(int i=0; i<=9; i++) if( cnt[i] ) ans /= J[cnt[i]];//去重
cout<<ans<<endl;
}
}

状压DP之排列perm的更多相关文章

  1. [BZOJ 1072] [SCOI2007] 排列perm 【状压DP】

    题目链接:BZOJ 1072 这道题使用 C++ STL 的 next_permutation() 函数直接暴力就可以AC .(使用 Set 判断是否重复) 代码如下: #include <io ...

  2. BZOJ1072 排列perm 【状压dp】

    Description 给一个数字串s和正整数d, 统计s有多少种不同的排列能被d整除(可以有前导0).例如123434有90种排列能 被2整除,其中末位为2的有30种,末位为4的有60种. Inpu ...

  3. B1072 [SCOI2007]排列perm 状压dp

    很简单的状压dp,但是有一个事,就是...我数组开大了一点,然后每次memset就会T,然后开小就好了!!!震惊!以后小心点这个问题. 题干: Description 给一个数字串s和正整数d, 统计 ...

  4. 排列perm HYSBZ - 1072(状压dp/暴力)

    Description 给一个数字串s和正整数d, 统计s有多少种不同的排列能被d整除(可以有前导0).例如123434有90种排列能被2整除,其中末位为2的有30种,末位为4的有60种. Input ...

  5. 「状压DP」「暴力搜索」排列perm

    「状压DP」「暴力搜索」排列 题目描述: 题目描述 给一个数字串 s 和正整数 d, 统计 sss 有多少种不同的排列能被 d 整除(可以有前导 0).例如 123434 有 90 种排列能被 2 整 ...

  6. 【BZOJ1072】【SCOI2007】排列 [状压DP]

    排列 Time Limit: 10 Sec  Memory Limit: 128 MB[Submit][Status][Discuss] Description 给一个数字串s和正整数d, 统计s有多 ...

  7. 暑假集训Day 4 P4163 [SCOI2007]排列 (状压dp)

    状压dp (看到s的长度不超过10就很容易想到是状压dp了 但是这个题的状态转移方程比较特殊) 题目大意 给一个数字串 s 和正整数 d, 统计 s 有多少种不同的排列能被 d 整除(可以有前导 0) ...

  8. K - Painful Bases 状压dp

    Painful Bases LightOJ - 1021 这个题目一开始看,感觉有点像数位dp,但是因为是最多有16进制,因为限制了每一个数字都不同最多就有16个数. 所以可以用状压dp,看网上题解是 ...

  9. HDU5816 Hearthstone(状压DP)

    题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=5816 Description Hearthstone is an online collec ...

随机推荐

  1. java实现第五届蓝桥杯猜年龄

    猜年龄 题目描述 小明带两个妹妹参加元宵灯会.别人问她们多大了,她们调皮地说:"我们俩的年龄之积是年龄之和的6倍".小明又补充说:"她们可不是双胞胎,年龄差肯定也不超过8 ...

  2. MySQL数据库基本使用(DDL)

    MySQL是一种开源的关系型数据库管理系统,并且因为其性能.可靠性和适应性而备受关注.下面是最近一个月MySQL.Oracle.SQL Server的百度指数搜索指数对比: 可以看到,在最近一个月,M ...

  3. 58同城Java面试

    总结这一次面试失败的不冤 很多知识,都是了解.知道,而没有做到明白与彻底的弄懂 差距还是比较大的 以后要多来写总结,提升自己,争取早日被认可 说说今天面试的主要内容和问题吧 希望大家集思广益 面试职位 ...

  4. Java 设置Excel单元格格式—基于Spire.Cloud.SDK for Java

    本文介绍使用Spire.Cloud.SDK for Java来设置Excel单元格格式,包括字体.字号.单元格背景.字体下滑线.字体加粗.字体倾斜.字体颜色.单元格对齐方式.单元格边框等 一.下载SD ...

  5. git环境配置 | GitHub

    注册完GitHub之后,需要配置git,其主要的目的是为了方便文件的上传.下载等. 一. git下载 https://git-scm.com/downloads 在git官网找到相应版本的git下载安 ...

  6. [CF696D]Legen...

    题目   点这里看题目. 分析   首先对于模式串建立 AC 自动机,并且计算出每个状态\(p\)的贡献总和\(con(p)\).   考虑一个朴素的 DP :   \(f(i,p)\):当前串长度为 ...

  7. AJAX的GET请求、POST请求

    感谢:链接(视频讲解很详细) AJAX(Asynchronous Javascript and XML):异步的JavaScript和XML(不需要刷新网页就可以更新网页数据) XML:百度百科 是一 ...

  8. (六)maven 聚合和继承

    项目目录 my_test 聚合pom <?xml version="1.0" encoding="UTF-8"?> <project xmln ...

  9. 动作函数-web_submit_data

    web_submit_data("login.pl", "Action=http://127.0.0.1:1080/WebTours/login.pl", &q ...

  10. CPU明明8个核,网卡为啥拼命折腾一号核?

    中断机制 我是CPU一号车间的阿Q,我又来了! 我们日常的工作就是不断执行代码指令,不过这看似简单的工作背后其实也并不轻松. 咱不能闷着头啥也不管一个劲的只管执行代码,还得和连接在主板上的其他单位打交 ...