BZOJ1025 [SCOI2009]游戏 【置换群 + 背包dp】
题目链接
题解
题意就是问一个\(1....n\)的排列在同一个置换不断重复下回到\(1...n\)可能需要的次数的个数
和置换群也没太大关系
我们只需知道同一个置换不断重复,实际上就是每个循环节的元素不断在循环节上旋转,所需次数就是所有循环节长度的\(lcm\)
这一点很显然
而循环节数量是任意的,长度也可以是任意的,但总和一定是\(n\)
问题就转化为了有多少个数\(x\)能为总和为\(n\)的一些数的\(lcm\)
如果令\(x = \prod\limits_{i = 1} p_i^{k_i}\)
若\(\sum\limits_{i = 1} p_i^{k_i} \le n\),那么\(x\)显然是可以被凑出来的
我们只需令每一个\(p_i^{k_i}\)作为一个数,再补上一些\(1\)使得它们总和为\(n\),那么它们就是一个合法的\(lcm\)为\(x\)的方案
问题就转化为了用\(\le n\)的一些质数\(p_i^{k_i}\)凑出\(\le n\)的数的方案数
显然就是一个分组背包问题
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<map>
#define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
#define REP(i,n) for (int i = 1; i <= (n); i++)
#define mp(a,b) make_pair<int,int>(a,b)
#define cls(s) memset(s,0,sizeof(s))
#define cp pair<int,int>
#define LL long long int
using namespace std;
const int maxn = 1005,maxm = 100005,INF = 1000000000;
inline int read(){
int out = 0,flag = 1; char c = getchar();
while (c < 48 || c > 57){if (c == '-') flag = -1; c = getchar();}
while (c >= 48 && c <= 57){out = (out << 3) + (out << 1) + c - 48; c = getchar();}
return out * flag;
}
LL f[maxn],ans;
int n,p[maxn],pi,isn[maxn];
void init(){
for (int i = 2; i <= n; i++){
if (!isn[i]) p[++pi] = i;
for (int j = 1; j <= pi && i * p[j] <= n; j++){
isn[i * p[j]] = true;
if (i % p[j] == 0) break;
}
}
}
int main(){
n = read();
init();
f[0] = 1;
for (int i = 1; i <= pi; i++){
for (int j = n; j >= 0; j--){
for (int k = p[i]; k <= j; k *= p[i])
f[j] += f[j - k];
}
}
for (int i = 0; i <= n; i++) ans += f[i];
printf("%lld\n",ans);
return 0;
}
BZOJ1025 [SCOI2009]游戏 【置换群 + 背包dp】的更多相关文章
- [bzoj1025][SCOI2009]游戏 (分组背包)
Description windy学会了一种游戏.对于1到N这N个数字,都有唯一 且不同的1到N的数字与之对应.最开始windy把数字按顺序1,2,3,……,N写一排在纸上.然后再在这一排下面写上它们 ...
- 2018.09.02 bzoj1025: [SCOI2009]游戏(计数dp+线筛预处理)
传送门 要将所有置换变成一个轮换,显然轮换的周期是所有置换长度的最小公倍数. 于是我们只需要求长度不超过n,且长度最小公倍数为t的不同置换数. 而我们知道,lcm只跟所有素数的最高位有关. 因此lcm ...
- bzoj千题计划116:bzoj1025: [SCOI2009]游戏
http://www.lydsy.com/JudgeOnline/problem.php?id=1025 题目转化: 将n分为任意段,设每段的长度分别为x1,x2,…… 求lcm(xi)的个数 有一个 ...
- [BZOJ1025][SCOI2009]游戏 DP+置换群
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1025 题目中的排数就是多少次回到原来的序列.很显然对于题目所描述的任意一种对应法则,其中一 ...
- BZOJ 1025: [SCOI2009]游戏 [置换群 DP]
传送门 题意:求$n$个数组成的排列变为升序有多少种不同的步数 步数就是循环长度的$lcm$..... 那么就是求$n$划分成一些数几种不同的$lcm$咯 然后我太弱了这种$DP$都想不出来.... ...
- bzoj1025: [SCOI2009]游戏(DP)
题目大意:将长度为n的排列作为1,2,3,...,n的置换,有可能置换x次之后,序列又回到了1,2,3,...,n,求所有可能的x的个数. 看见这种一脸懵逼的题第一要务当然是简化题意...我们可以发现 ...
- bzoj1025 [SCOI2009]游戏——因数DP
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1025 这篇博客写得真好呢:https://www.cnblogs.com/phile/p/4 ...
- [BZOJ1025] [SCOI2009]游戏 解题报告
Description windy学会了一种游戏.对于1到N这N个数字,都有唯一且不同的1到N的数字与之对应.最开始windy把数字按顺序1,2,3,……,N写一排在纸上.然后再在这一排下面写上它们对 ...
- SCOI2009游戏 (数论+dp)
题解 很显然,对于一个确定的排列,每个数字的移动规则是一定的,我们根据这个排列,把它抽象为i向a[i]连一条边,很显然最后会构成一个环,那么行数就是这些环长的lcm. 那么问题变成了把n任意进行划分, ...
随机推荐
- Make a Person-freecodecamp算法题目
Make a Person 1.要求 用下面给定的方法构造一个对象:方法有 getFirstName(), getLastName(), getFullName(), setFirstName(fir ...
- C#基础-面向对象-继承
继承 新建一个基类 对Person类3个字段进行重构->封装字段 效果如下: public string Name { get => name; set => name = valu ...
- python——numpy_1图像基本操作
1.图像的数组表示: from PIL import Image from pylab import * from numpy import * im = array(Image.open('E:\P ...
- Android stadio 自定义debug release keystore
1.添加siggnig name 随意,不过按我写的就可以了.设置完成之后,你的build.grade就会多出来一些: android { signingConfigs { signingConfig ...
- 获取HTTP请求头中的地址
技术交流群:233513714 public static String getIpAddr(HttpServletRequest request) { String ip = request.get ...
- jsUnpacker
EVAL function executeEval(){ let evalCodeElt = document.getElementById("eval_code"); let e ...
- django之python3.4及以上连接mysql的一些问题记录
首先,祭出大杀器whl https://www.lfd.uci.edu/~gohlke/pythonlibs/#mysqlclient django1.x与django2.x 在项目的写法上有一些区别 ...
- 如何高性能的给 UIImageView 加个圆角?
不好的解决方案 使用下面的方式会强制Core Animation提前渲染屏幕的离屏绘制, 而离屏绘制就会给性能带来负面影响,会有卡顿的现象出现 self.view.layer.cornerRadius ...
- 剑指Offer - 九度1508 - 把字符串转换成整数
剑指Offer - 九度1508 - 把字符串转换成整数2014-02-06 23:46 题目描述: 将一个字符串转换成一个整数,要求不能使用字符串转换整数的库函数. 输入: 输入可能包含多个测试样例 ...
- 《Cracking the Coding Interview》——第6章:智力题——题目6
2014-03-20 01:14 题目:有100栈灯,一开始都关着.如果你按照n从1~100的顺序,每次都掰一下n的倍数的开关(开->关,关->开),那么到最后有多少灯是亮的? 解法:这个 ...