BZOJ 1025: [SCOI2009]游戏( 背包dp )

显然题目要求长度为n的置换中各个循环长度的lcm有多少种情况.

判断一个数m是否是满足题意的lcm. m = ∏ piai, 当∑pia≤ n时是满足题意的. 最简单我们令循环长度分别为piai,不足n的话,我们令其他循环长度为1, 补到=n为止. 这样它们的lcm显然是=m的.

然后就是一个背包了...dp(i, j) = dp(i - 1, j) + ∑1≤t≤adp( i - 1, j - p) 表示前i个质数, 和为j有多少中方案

#include<bits/stdc++.h>

using namespace std;

typedef long long ll;

const int maxn = 1009;

ll dp[2][maxn];
int prime[maxn], N = 0, n;
bool check[maxn];

void init() {
	memset(check, 0, sizeof check);
	for(int i = 2; i <= n; i++) {
		if(!check[i])
		    prime[N++] = i;
		for(int j = 0; j < N && i * prime[j] <= n; j++) {
			check[i * prime[j]] = true;
			if(i % prime[j] == 0) break;
		}
	}
}

int main() {

	cin >> n;
	init();

	int c = 0, p = 1;
	memset(dp[c], 0, sizeof dp[c]); dp[c][0] = 1;
	for(int i = 0; i < N; i++) {
		swap(c, p);
		memcpy(dp[c], dp[p], sizeof dp[c]);
		for(int t = prime[i]; t <= n; t *= prime[i])
		    for(int j = t; j <= n; j++)
			    dp[c][j] += dp[p][j - t];
	}
	ll ans = 0;
	for(int i = 0; i <= n; i++) ans += dp[c][i];
	cout << ans << endl;

	return 0;
}

  

1025: [SCOI2009]游戏

Time Limit: 1 Sec  Memory Limit: 162 MB
Submit: 1558  Solved: 977
[Submit][Status][Discuss]

Description

windy学会了一种游戏。对于1到N这N个数字,都有唯一且不同的1到N的数字与之对应。最开始windy把数字按顺序1,2,3,……,N写一排在纸上。然后再在这一排下面写上它们对应的数字。然后又在新的一排下面写上它们对应的数字。如此反复,直到序列再次变为1,2,3,……,N。 如: 1 2 3 4 5 6 对应的关系为 1->2 2->3 3->1 4->5 5->4 6->6 windy的操作如下 1 2 3 4 5 6 2 3 1 5 4 6 3 1 2 4 5 6 1 2 3 5 4 6 2 3 1 4 5 6 3 1 2 5 4 6 1 2 3 4 5 6 这时,我们就有若干排1到N的排列,上例中有7排。现在windy想知道,对于所有可能的对应关系,有多少种可能的排数。

Input

包含一个整数,N。

Output

包含一个整数,可能的排数。

Sample Input

【输入样例一】
3
【输入样例二】
10

Sample Output

【输出样例一】
3
【输出样例二】
16

HINT

【数据规模和约定】

100%的数据,满足 1 <= N <= 1000 。

Source

时间: 2024-12-22 07:01:11

BZOJ 1025: [SCOI2009]游戏( 背包dp )的相关文章

[BZOJ 1025] [SCOI2009] 游戏 【DP】

题目链接:BZOJ - 1025 题目分析 显然的是,题目所要求的是所有置换的每个循环节长度最小公倍数的可能的种类数. 一个置换,可以看成是一个有向图,每个点的出度和入度都是1,这样整个图就是由若干个环构成,这些环的长度和为 n . 因此,就是要求出和为 n 的正整数的最小公倍数的可能情况. 有一个性质:这些正整数中有合数存在的最小公倍数,都可以用全是质数的情况包含. 所以我们只要求出用质数组成的情况就可以了.我们要求的就是,若干个质数,它们的和小于等于 n,它们的最小公倍数情况. 先筛法求出

bzoj 1025 [SCOI2009]游戏(置换群,DP)

[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1025 [题意] 给定n,问1..n在不同的置换下变回原序列需要的不同排数有多少种. [思路] 对于一个置换,如果分解后的到的循环长度为 A1,A2,A3… 则答案为lcm(A1,A2…)的不同种数,即有多少个不同的lcm满足: A1+A2+A3+…=n lcm=lcm(A1,A2,A3…) 对于A[1..]的lcm, lcm=a1^max{p1}*a2^max{p2}.. 只考虑ma

bzoj 1025 [SCOI2009]游戏 dp

题面 题目传送门 解法 显然,可以回到初始状态就意味着一定由若干个环组成 假设环的长度为\(l_i\) 那么,我们可以得到\(\sum l_i=n\) 不考虑自环的情况,那么\(\sum l_i≤n\) 将\(n\)以内的质因数全部筛出,强制每一次只取某一个质数的次幂,那么就可以解决重复计数的问题 时间复杂度:\(O(n^2)\) 代码 #include <bits/stdc++.h> #define int long long #define N 1010 using namespace s

BZOJ 1025 [SCOI2009]游戏

之前找LLJ大佬推荐水题的时候让我做这个,然后不出意料的我不会. 日常抄题解. 手玩几组数据发现它N个数可以分成多个组,每个组为一个循环,他们的LCM就是最后的层数. 预处理出n以内的所有质数,我们可以把n分解成p1^a1+p2^a2+p3^a3...不同的p之间的lcm数可以直接相乘,我们用dp递推地算答案,dp[i][j表示前i个质数和为j的lcm数,然后就可以DP了. 最后统计答案要把0~n的dp[p[0]][i]加起来,因为每个数可以单成一组. #include<cstdio> #in

BZOJ 1025 SCOI2009 游戏 动态规划

题目大意:给定n,定义一个置换的排数为1~n的循环经过这个置换最少T次(T>0)可以回到原来的序列 求所有可能的排数的数量 将一个置换分解为一些循环,那么这个置换的排数就是这些循环的长度的最小公倍数 于是对于一个数,我们验证这个数是否是排数的方式就是将这个数分解质因数,令x=p1^a1*p2^a2*...*pk^ak,若p1^a1+p2^a2+...+pk^ak<=n,则x就是可能的排数 分组背包即可 令f[i][j]表示用前i个质数,和为j能得出的数的数量 每组的物品是pi^1~pi^ai

BZOJ 4247 挂饰 背包DP

4247: 挂饰 Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/problem.php?id=4247 Description JOI君有N个装在手机上的挂饰,编号为1...N. JOI君可以将其中的一些装在手机上. JOI君的挂饰有一些与众不同——其中的一些挂饰附有可以挂其他挂件的挂钩.每个挂件要么直接挂在手机上,要么挂在其他挂件的挂钩上.直接挂在手机上的挂件最多有1个. 此外,每个挂件

bzoj1025 [SCOI2009]游戏——因数DP

题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1025 这篇博客写得真好呢:https://www.cnblogs.com/phile/p/4473192.html 代码如下: #include<iostream> #include<cstdio> #include<cstring> using namespace std; int n,pri[1005],cnt; long long f[1005][1005]

【BZOJ 1025】 [SCOI2009]游戏

1025: [SCOI2009]游戏 Time Limit: 1 Sec  Memory Limit: 162 MB Submit: 1273  Solved: 805 [Submit][Status] Description windy学会了一种游戏.对于1到N这N个数字,都有唯一且不同的1到N的数字与之对应.最开始windy把数字按顺序1,2,3,--,N写一排在纸上.然后再在这一排下面写上它们对应的数字.然后又在新的一排下面写上它们对应的数字.如此反复,直到序列再次变为1,2,3,--,N

SCOI2009游戏

1025: [SCOI2009]游戏 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 1065  Solved: 673[Submit][Status] Description windy学会了一种游戏.对于1到N这N个数字,都有唯一且不同的1到N的数字与之对应.最开始windy把数字按顺序1,2,3,……,N写一排在纸上.然后再在这一排下面写上它们对应的数字.然后又在新的一排下面写上它们对应的数字.如此反复,直到序列再次变为1,2,3,……,N.