暑假集训Day 4 P4163 [SCOI2007]排列 (状压dp)
状压dp
(看到s的长度不超过10就很容易想到是状压dp了
但是这个题的状态转移方程比较特殊)
题目大意
给一个数字串 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
算法分析
- 这个题的思路还是蛮偏的,,,,但是很好理解
我们将f数组的第一维定义为状态 (最大值为1<<10) 第二维定义为 余数
那么问题就来了 如果我们把第一维定义为状态的话 应该是怎样的状态呢?
还是一样举个栗子:
给出的数为1234 我们就定义一个1<<4大小的状态 然后每一位表示对应该位置的数是否已经添加
比如0101就表示此时我们已经添加了2和4还有1和3没有添加进去 下一次可以选择添加进去1或者3 - 循环顺序
第一层循环状态 第二层循环余数 第三层循环下一个添加的数字
则转移方程就是f[i|1<<k][(j * 10+k)%d] += f[i][j]
第一维是i|1<<k 显然就是加上k位置的数字
第二维是(j * 10+k)%d 即上一位的余数再加上当前位 然后整个再%d
*转移条件
如果当前状态向下个状态转移的时候 即加上第k位置数字 这个已经转移过了 那么显然就不能再加一次了
判断语句就是
if((i & (1<<k)) == 0)
此时状态为i 想要转移的状态为i|1<<k 如果i&1<<k != 0 即表示i在第k位为1 也就是表示这个状态已经转移过了 所以要保证==0的时候再转移
- 需要注意有的数字是重复的 显然根据排列组合的规律 除以这个重复数字的全排列即可 即除以该数的阶乘(可以预处理或者写个函数 这里提供函数的代码)
代码展示
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5+10;
int f[1<<10][1001],T,a[maxn],d,cnt[11];
char s[maxn];
int jc(int x){
int u = 1;
for(int i = 1;i <= x;++i)u *= i;
return u;
}
int main(){
scanf("%d",&T);
while(T--){
scanf("%s%d",s,&d);
int len = strlen(s);
memset(cnt,0,sizeof(cnt));
memset(f,0,sizeof(f));
for(int i = 0;i < len;++i){
a[i] = s[i] - '0';
cnt[a[i]]++;
}
int maxs = (1<<len)-1;
f[0][0] = 1;
for(int i = 0;i <= maxs;++i){
for(int j = 0;j < d;++j)
if(f[i][j])
for(int k = 0;k < len;++k)
if((i & (1<<k)) == 0)
f[i|(1<<k)][(j*10+a[k])%d] += f[i][j];
}
int ans = f[maxs][0];
for(int i = 0;i <= 9;++i){
if(cnt[i]!=0)ans/=jc(cnt[i]);
}
printf("%d\n",ans);
}
return 0;
}
谢谢观看
点个关注>)<
暑假集训Day 4 P4163 [SCOI2007]排列 (状压dp)的更多相关文章
- 【BZOJ1072】【SCOI2007】排列 [状压DP]
排列 Time Limit: 10 Sec Memory Limit: 128 MB[Submit][Status][Discuss] Description 给一个数字串s和正整数d, 统计s有多 ...
- LOJ #6037.「雅礼集训 2017 Day4」猜数列 状压dp
这个题的搜索可以打到48分…… #include <cstdio> #include <cstring> #include <algorithm> ; bool m ...
- P4163 [SCOI2007]排列——next_permutation
P4163 [SCOI2007]排列 注意要排序: next_permutation prev_permutation #include<cstdio> #include<cstri ...
- 暑假集训Day2 互不侵犯(状压dp)
这又是个状压dp (大型自闭现场) 题目大意: 在N*N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子. ...
- [BZOJ 1072] [SCOI2007] 排列perm 【状压DP】
题目链接:BZOJ 1072 这道题使用 C++ STL 的 next_permutation() 函数直接暴力就可以AC .(使用 Set 判断是否重复) 代码如下: #include <io ...
- B1072 [SCOI2007]排列perm 状压dp
很简单的状压dp,但是有一个事,就是...我数组开大了一点,然后每次memset就会T,然后开小就好了!!!震惊!以后小心点这个问题. 题干: Description 给一个数字串s和正整数d, 统计 ...
- LUOGU P4163 [SCOI2007]排列
传送门 解题思路 首先我们发现这道题s的长度很小,所以考虑点暴力的做法,状压dp或搜索.本蒟蒻搜索永远调不对,所以就写了个状压dp.因为所有s里的数都要出现一次,并且最后的答案是要求整除,那么我们设d ...
- 暑假集训 || 状压DP
emm 位操作实现技巧: 获得第i位的数据: if(!(data & (1<< i))) 则data的第 i 位为0,else 为 1 设置第i位为1,data=(data | ...
- 暑假集训Day2 状压dp 特殊方格棋盘
首先声明 : 这是个很easy的题 可这和我会做有什么关系 题目大意: 在n*n的方格棋盘上放置n个车,某些格子不能放,求使它们不能互相攻击的方案总数. 注意:同一行或同一列只能有一个车,否则会相互攻 ...
随机推荐
- 线程池续:你必须要知道的线程池submit()实现原理之FutureTask!
前言 上一篇内容写了Java中线程池的实现原理及源码分析,说好的是实实在在的大满足,想通过一篇文章让大家对线程池有个透彻的了解,但是文章写完总觉得还缺点什么? 上篇文章只提到线程提交的execute( ...
- Java工作流框架jflow 集团应用模式用户组功能
关键字 驰骋BPM ,工作流开发框架,用户组,接受人规则,用户组发起人范围,选择人范围. 集团工作模式. Ccflow ,jflow.工作流引擎 名词定义与应用背景 对于集团模式的ccflow,jfl ...
- jchdl - RTL实例 - Adder4Carry
https://mp.weixin.qq.com/s/j4zLmjKgau2vRXVNfm0SIA 带进位的加法. 参考链接 https://github.com/wjcdx/jchdl/bl ...
- Java实现 LeetCode 365 水壶问题
365. 水壶问题 有两个容量分别为 x升 和 y升 的水壶以及无限多的水.请判断能否通过使用这两个水壶,从而可以得到恰好 z升 的水? 如果可以,最后请用以上水壶中的一或两个来盛放取得的 z升 水. ...
- 【Vue】axios封装,更好的管理api接口和使用
在现在的前端开发中,前后端分离开发比较主流,所以在封装方法和模块化上也是非常需要掌握的一门技巧.而axios的封装也是非常的多,下面的封装其实跟百度上搜出来的axios封装或者axios二次封装区别不 ...
- 【网页设计】第四周 JavaSript
第四周 JSP 一 JSP概述 含义: Java Server Pages, 广泛使用的服务器端脚本语言之一:(运行在服务器端 BS结构) 由服务器端的JSP引擎执行JSP代码,然后将结果以HT ...
- 创建使用mysql表
1.展示所有数据库 show databases;2.选中数据库 use database_name(;)3.创建数据库 create database database_name;4.使用2选中数据 ...
- Docker+Selenium+TestNG+Maven+Jenkins环境搭建
一.Selenium环境准备 standalone-chrome Docker容器启动: docker pull selenium/standalone-chrome version: '3' ser ...
- 百度编辑器UEditor不能插入视频的解决方法
在编辑器中就可以引用优酷.腾讯视频的iframe通用代码和embed html代码:移动端一般引用iframe,可设置属性,使其适应设备.(这里,建议切换到源码模式,插入相应的视频代码embed或if ...
- mybatis 学习教程
https://www.cnblogs.com/ashleyboy/category/1246107.html