题解 P4163 [SCOI2007]排列
强烈谴责只有 125MB 的行为,然后我没删调试是个什么 SB。。。
闲话少说,切入正题——
首先看到取余和数字是可以排列的,我们自然而然的想到了数位 dp,但是很显然这题不是的数位 dp 通常解决的是 \(1\sim k\) 之间符合要求的数这里是恰好符合的。
发现 \(s\) 长度很小,只有 \(15\),所以考虑状压。
然后这个时候 SX 还没看出来是状压足以见得他是个瞎子了!
如果数据范围很小还是个 dp 一定要考虑状压!!!!!
如果数据范围很小还是个 dp 一定要考虑状压!!!!!
也就 SX 这种带聪明想不到状压了吧/qd
然后就很显然要记录余数,设 \(f_{i, S}\) 为选择状态为 \(S\) 余数为 \(i\) 的方案数。
如果我们要加入一个数字,首先他要不在 \(S\) 内(一直没判这个调了很长时间,所以我是压根不会状压石锤,这种弱智玩意儿都没看出来),然后转移很显然 \(f_{(10i + a_j)\bmod d, S|(1<<j)} += f_{i, S}\)。
重复数字除以它出现次数阶乘即可。
代码:
//SIXIANG
#include <iostream>
#include <string>
#include <algorithm>
#include <cstring>
#define MAXN 1000
#define int long long
#define QWQ cout << "QWQ" << endl;
using namespace std;
int f[MAXN + 10][(1 << 10) + 10], arr[10], t[10], frac[16];
void pre() {
frac[0] = 1;
for(int p = 1; p <= 16; p++) frac[p] = frac[p - 1] * p;
}
signed main() {
pre();
int T; cin >> T;
string str; int d;
while(T--) {
cin >> str >> d;
memset(t, 0, sizeof(t));
memset(arr, 0, sizeof(arr));
memset(f, 0, sizeof(f));
int i = 0;
for(int p = 0; p < str.size(); p++)
t[str[p] - '0']++, arr[p] = str[p] - '0';
f[0][0] = 1;
int len = str.size();
for(int S = 0; S < (1 << len); S++)
for(int p = 0; p < len; p++)
for(int i = 0; i < d; i++)
if(!((S >> p) & 1))
f[(10 * i + arr[p]) % d][S | (1 << p)] += f[i][S];
for(int p = 0; p <= 9; p++)
f[0][(1 << len) - 1] /= frac[t[p]];
cout << f[0][(1 << len) - 1] << endl;
}
}
顺便提一嘴,这里面枚举 S 要放在外层循环。因为显然余数一维不可能作为阶段。
以及 500ms 确实有点卡。
题解 P4163 [SCOI2007]排列的更多相关文章
- P4163 [SCOI2007]排列——next_permutation
P4163 [SCOI2007]排列 注意要排序: next_permutation prev_permutation #include<cstdio> #include<cstri ...
- LUOGU P4163 [SCOI2007]排列
传送门 解题思路 首先我们发现这道题s的长度很小,所以考虑点暴力的做法,状压dp或搜索.本蒟蒻搜索永远调不对,所以就写了个状压dp.因为所有s里的数都要出现一次,并且最后的答案是要求整除,那么我们设d ...
- 暑假集训Day 4 P4163 [SCOI2007]排列 (状压dp)
状压dp (看到s的长度不超过10就很容易想到是状压dp了 但是这个题的状态转移方程比较特殊) 题目大意 给一个数字串 s 和正整数 d, 统计 s 有多少种不同的排列能被 d 整除(可以有前导 0) ...
- BZOJ 1072: [SCOI2007]排列perm 状态压缩DP
1072: [SCOI2007]排列perm Description 给一个数字串s和正整数d, 统计s有多少种不同的排列能被d整除(可以有前导0).例如123434有90种排列能被2整除,其中末位为 ...
- SCOI2007排列perm
1072: [SCOI2007]排列perm Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 805 Solved: 497[Submit][Stat ...
- BZOJ 1072 [SCOI2007]排列perm
1072: [SCOI2007]排列perm Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1268 Solved: 782[Submit][Sta ...
- [BZOJ1072][SCOI2007]排列perm 状压dp
1072: [SCOI2007]排列perm Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2488 Solved: 1546[Submit][St ...
- [BZOJ1072][SCOI2007] 排列prem
Description 给一个数字串s和正整数d, 统计s有多少种不同的排列能被d整除(可以有前导0).例如123434有90种排列能被2整除,其中末位为2的有30种,末位为4的有60种. Input ...
- 【BZOJ】1072: [SCOI2007]排列perm(状压dp+特殊的技巧)
http://www.lydsy.com/JudgeOnline/problem.php?id=1072 首先无限膜拜题解orz表示只会暴力orz 数据那么小我竟然想不到状压! orz 这种题可以取模 ...
- 【62.89%】【BZOJ 1072】[SCOI2007]排列perm
Time Limit: 10 Sec Memory Limit: 128 MB Submit: 1862 Solved: 1171 [Submit][Status][Discuss] Descri ...
随机推荐
- Day30:ArrayList详解
ArrayList 1.1 集合概述 当我们要存储多个数据时,固定长度的数组存储格式已经满足不了我们的需要了,且不能满足变化的需求: Java中集合类则可以解决我们的需求 特点:提供一种存储空间可变的 ...
- Linux常用软件的安装及Nginx的使用
主要内容: 软件安装方式 上传与下载工具 常用软件的安装--jdk.tomcat.mysql.redis 项目的部署 Nginx的安装 Nginx的功能 静态网站部署 虚拟主机配置及端口绑定 域名绑定 ...
- 【每日一题】【回溯backtrace】N皇后
n 皇后问题 研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击. 给你一个整数 n ,返回所有不同的 n 皇后问题 的解决方案. 每一种解法包含一个不同的 n 皇后问 ...
- Qt操作Json小结
Qt操作Json 1.QJsonDocument 1.详细说明 QJsonDocument类提供了读写JSON文档的方法. QJsonDocument是一个封装了完整JSON文档的类,可以从基于UTF ...
- pythonfloat优雅的四舍五入
开发中经常会有float四舍五入转int的需求,先看看浮点数直接转int的情形:无论如何float直接转int都不会四舍五入,而是直接抹去小数点. 这个需求很简单,实现也很简单,看过网友的实现,都不够 ...
- Flask初步认识
1.Flask基本认识 Flask 本身相当于一个内核,其他几乎所有的功能都要用到扩展包(数据库Flask-SQLAlchemy),都需要用第三方的扩展来实现.比如可以用 Flask 扩展加入ORM. ...
- Python二维码扫描
原文链接:https://blog.easyctf.cn/Moxin/59365.html 模块准备 1.pyzbar pip install pyzbar 2.PIL 注意:PIL只支持Python ...
- [cocos2d-x]判断两个矩形是否有交叉区域
bool Rect::intersectsRect(const Rect& rect) const { return !( getMaxX() < rect.getMinX() || r ...
- Linux基础操作-02
Linux操作 Linux操作权限 显示详细信息之后,文件地权限显示 drwxrwxrwx "-" 表示常规文件 d 目录文件 b 块特殊设备 c 字符特殊设备文件 p 管道设备文 ...
- (17)go-micro微服务Prometheus监控
目录 一 Prometheus监控介绍 1.微服务监控系统promethues介绍 2.微服务监控系统promethues工作流程 二 Prometheus监控重要组件和重要概念 1.微服务监控系统p ...