排列perm HYSBZ - 1072(状压dp/暴力)
Description
给一个数字串s和正整数d, 统计s有多少种不同的排列能被d整除(可以有前导0)。例如123434有90种排列能
被2整除,其中末位为2的有30种,末位为4的有60种。
Input
输入第一行是一个整数T,表示测试数据的个数,以下每行一组s和d,中间用空格隔开。s保证只包含数字0, 1
, 2, 3, 4, 5, 6, 7, 8, 9.
Output
每个数据仅一行,表示能被d整除的排列的个数。
Sample Input
000 1
001 1
1234567890 1
123434 2
1234 7
12345 17
12345678 29
Sample Output
3
3628800
90
3
6
1398
HINT
在前三个例子中,排列分别有1, 3, 3628800种,它们都是1的倍数。
【限制】
100%的数据满足:s的长度不超过10, 1<=d<=1000, 1<=T<=15
题解

其中判断语句的含义是在II状态中,KK号没有选择出来。
状态转移结束后,由于数串中可能存在重复的数字(样例已经给出来了),这个时候我们就会有许多重复的计算。这个问题很好解决,我们根据排列的知识将最后的Ans/=Cnt[I] Cnt[I] 记录数字I在数串中出现的次数)就可以了。
C++代码/暴力
#include<bits/stdc++.h>
using namespace std;
int a[],b[];
int n ,d;
int ans ;
void dfs(int i,long long x){
if(i > n){ if(x % d == ) ans ++;
return;
}
for(int j = ;j <= ;j ++){
if(b[j]) {
--b[j];
dfs(i + ,x * + j);
++b[j];
}
}
} int main(){
int t;
cin >> t;
while(t--){
string str;
cin >> str;
ans = ;
n = str.size();
memset(a,,sizeof a);
memset(b,,sizeof b);
for(int i = ; i < str.size() ; i++){
a[i] = str[i] - '';
b[a[i]]++;
}
cin >> d;
dfs(,);
cout << ans << endl;
}
}
C++代码/状压
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define DB double
#define SG string
#define LL long long
#define DP(A,B) DP[A][B]
#define Fp(A,B,C,D) for(A=B;A<=C;A+=D)
#define Fm(A,B,C,D) for(A=B;A>=C;A-=D)
#define Clear(A) memset(A,0,sizeof(A))
using namespace std;
const LL Mod=1e9+;
const LL Max=2e3+;
const LL Inf=1e18;
LL T,M,Num[Max],Cnt[Max],DP[Max][Max];
inline LL Read(){
LL X=;char CH=getchar();bool F=;
while(CH>''||CH<''){if(CH=='-')F=;CH=getchar();}
while(CH>=''&&CH<=''){X=(X<<)+(X<<)+CH-'';CH=getchar();}
return F?-X:X;
}
inline void Write(LL X){
if(X<)X=-X,putchar('-');
if(X>)Write(X/);
putchar(X%+);
}
int main(){
LL I,J,K,L;
T=Read();
while(T--){
Clear(Cnt);Clear(DP);
char CH[];scanf("%s",CH+);
LL Length=strlen(CH+);M=Read();
Fp(I,,Length,){
Num[I]=CH[I]-'';
Cnt[Num[I]]++;
}DP(,)=;
K=(<<Length)-;
Fp(I,,K,){
Fp(J,,M-,){
Fp(L,,Length,){
if((I&(<<(L-)))==){
DP(I|(<<(L-)),((J<<)+(J<<)+Num[L])%M)+=DP(I,J);
}
}
}
}LL Ans=DP(K,);
Fp(I,,,){
Fp(J,,Cnt[I],){
Ans/=J;
}
}Write(Ans);putchar('\n');
}
return ;
}
排列perm HYSBZ - 1072(状压dp/暴力)的更多相关文章
- N - 寿司晚宴 HYSBZ - 4197 状压dp
N - 寿司晚宴 HYSBZ - 4197 推荐题解 这个题目我觉得还是很难的,借助题解写出来的,题解还看了很久,现在还是不是很理解. 首先这个数比较大有500,如果直接就像这个题目S - Query ...
- bzoj 1072状压DP
1072: [SCOI2007]排列perm Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2293 Solved: 1448[Submit][St ...
- bzoj 1072 状压DP
我们用w[i][j]来表示,i是一个二进制表示我们选取了s中的某些位,j表示这些位%d为j,w[i][j]则表示这样情况下的方案数,那么我们可以得到转移.w[i|(1<<k)][(j*10 ...
- K - Painful Bases 状压dp
Painful Bases LightOJ - 1021 这个题目一开始看,感觉有点像数位dp,但是因为是最多有16进制,因为限制了每一个数字都不同最多就有16个数. 所以可以用状压dp,看网上题解是 ...
- [BZOJ 1072] [SCOI2007] 排列perm 【状压DP】
题目链接:BZOJ 1072 这道题使用 C++ STL 的 next_permutation() 函数直接暴力就可以AC .(使用 Set 判断是否重复) 代码如下: #include <io ...
- 「状压DP」「暴力搜索」排列perm
「状压DP」「暴力搜索」排列 题目描述: 题目描述 给一个数字串 s 和正整数 d, 统计 sss 有多少种不同的排列能被 d 整除(可以有前导 0).例如 123434 有 90 种排列能被 2 整 ...
- BZOJ1072 排列perm 【状压dp】
Description 给一个数字串s和正整数d, 统计s有多少种不同的排列能被d整除(可以有前导0).例如123434有90种排列能 被2整除,其中末位为2的有30种,末位为4的有60种. Inpu ...
- B1072 [SCOI2007]排列perm 状压dp
很简单的状压dp,但是有一个事,就是...我数组开大了一点,然后每次memset就会T,然后开小就好了!!!震惊!以后小心点这个问题. 题干: Description 给一个数字串s和正整数d, 统计 ...
- CCF 201312-4 有趣的数 (数位DP, 状压DP, 组合数学+暴力枚举, 推公式, 矩阵快速幂)
问题描述 我们把一个数称为有趣的,当且仅当: 1. 它的数字只包含0, 1, 2, 3,且这四个数字都出现过至少一次. 2. 所有的0都出现在所有的1之前,而所有的2都出现在所有的3之前. 3. 最高 ...
随机推荐
- layui.form is not a function
改变: var form = layui.form; 如果你是从1.x升级2.x造成的,那只需要在定义的时候吧后面的()去掉就可以了.请关注更新日志:1.x 升 2.0 特别注意事项layDate日期 ...
- 1.端口被占用问题:Embedded servlet container failed to start. Port 8097 was already in use.
1.端口被占用问题:Embedded servlet container failed to start. Port 8097 was already in use.netstat -anonetst ...
- [CF118D]Caesar's Legions 题解
题意简述 一个01序列由\(n_1\)个0和\(n_2\)个1组成,求最长连续0串长度不超过\(k_1\),最长连续1串长度不超过\(k_2\)的序列的方案总数 题解 状态 方案总数 变量 已经取了i ...
- Task的用法
创建任务 无返回值的方式 方式1: var t1 = new Task(() => TaskMethod("Task 1")); t1.Start(); Task.WaitA ...
- Logger工具类
org.slf4j.Logger的简单封装,传入所在类的class,和类名或全类名. public class LoggerFactory { public static Logger getLogg ...
- python学习之路(23)
类和实例 面向对象最重要的概念就是类(Class)和实例(Instance),必须牢记类是抽象的模板,比如Student类,而实例是根据类创建出来的一个个具体的“对象”,每个对象都拥有相同的方法,但各 ...
- hive里面union all的用法记录
UNION用于联合多个select语句的结果集,合并为一个独立的结果集,结果集去重. UNION ALL也是用于联合多个select语句的结果集.但是不能消除重复行.现在hive只支持UNION AL ...
- 测试相关shell命令总结2——结构控制语句,命令行参数
1,shell 中单引号和双引号的区别,单引号不进行解释.双引号进行解释 1,在shell中进行数学运算,放在$和[]中 $[1+2] 有些很奇怪,在.sh文件中放在(())中貌似也能够进行数学运算. ...
- Linux读写执行权限
Linux 将访问文件的用户分为 3 类,分别是文件的所有者,所属组(也就是文件所属的群组)以及其他人. 最常见的文件权限有 3 种,即对文件的读(用 r 表示). 写(用 w 表示). 执行(用 x ...
- jdk环境配置(windows版)
JAVA_HOME C:\Program Files\Java\jdk1.7.0_80 Path %JAVA_HOME%\bin;%JAVA_HOME%\jre\bin; CLASSPATH .;%J ...