ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

题解 P4163 [SCOI2007]排列

2022-08-02 13:31:15  阅读:123  来源: 互联网

标签:arr include int 题解 状压 P4163 str SCOI2007 dp


强烈谴责只有 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 确实有点卡。

标签:arr,include,int,题解,状压,P4163,str,SCOI2007,dp
来源: https://www.cnblogs.com/thirty-two/p/16543416.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有