NOIp模拟3 游戏

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了NOIp模拟3 游戏相关的知识,希望对你有一定的参考价值。

试题描述

  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想知道,对于所有可能的对应关系,有多少种可能的排数。

输入格式

一个整数N

输出格式

一个整数,可能的排数。

输入示例

输入样例一:
3

输入样例二:
10
 

输出示例

输出样例一:
3

输出样例二:
16

注释说明

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

 

 

【分析】

对于原序列,每个数都有唯一且不同的数与之对应,这很像函数关系。

而对于对应序列,每个数的原像的是唯一的,所以序列中必定有若干个首尾相接的环,所有环中的数的总和为n。

又因为一个长度为m的环经过k*m次变换可以回到原来的状态,所以这个问题转化成了求若干个和为n的数的最小公倍数有多少种。

再因为若干个数的LCM是这若干个数中出现过的质因数中最高幂的乘积,而质数幂都是不同的,所以这个问题最后转化成了完全背包问题...

注意这里不足n的话可以用1补齐,任何数乘1都还是原数,这里也相当于背包可以不装满。

 

【代码】

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 int n, len=1;
 5 long long ans;
 6 long long a[1020], dp[1020];
 7 int pr[200]={0, 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73,
 8 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163,
 9  167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251,
10  257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349,
11  353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443,
12  449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557,
13  563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647,
14  653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757,
15  761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863,
16  877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983,
17  991, 997};//偷懒打了个质数表
18 
19 int main() {
20     cin >> n;        
21     dp[0]=1;
22     for (int i=1;i<=168;++i) 
23         for (int j=n;j>=pr[i];--j)
24             for (int k=pr[i];k<=j;k*=pr[i])
25                 dp[j]+=dp[j-k];
26     for (int i=0;i<=n;++i)
27         ans+=dp[i];
28     cout << ans << endl;
29 }

 

以上是关于NOIp模拟3 游戏的主要内容,如果未能解决你的问题,请参考以下文章

NOIp 2013 #3 转圈游戏 Label:模拟

NOIP模拟赛(2017.9.15) -游戏(game)

JZOJ.5306NOIP2017模拟8.18棋盘游戏

NOIP模拟赛皇后游戏

NOIp模拟2 日历游戏

noip模拟赛 圆桌游戏