zoukankan      html  css  js  c++  java
  • bzoj1025: [SCOI2009]游戏(数学 + 思维 + DP)

    原题链接

    题目描述: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,1 <= N <= 1000。

    输出格式:包含一个整数,可能的排数。

    输入样例
    10

    输出样例
    16

    解析:可以发现,每个置换都有各自的循环节,而最后的排数就是每个循环节长度的lcm+1。
       如题目描述中的循环为[1 2 3][4 5][6]。
       列数为lcm(3,2,1)+1=6+1=7。
       于是题目就转化成了:给定一个数n,将它分为若干个数的和后,求这些数的lcm的种数。
       而若干个数的lcm就是这些数相同质因数最大次幂的积。
       即(lcm=p1^{max(c1)} imes p2^{max(c2)}...pn^{max(cn)})
       若有一个数(A=p1^{c1} imes p2^{c2},B=p1^{c1},C=p2^{c2})
       那么显然A对答案的贡献与B和C对答案的贡献是一样的。
       而(B+C<B imes C=A),所以可以将A拆成B和C。
       于是题目又被转化成了:(p1^{c1}+p2^{c2}...pn^{cn}=n)的个数。
       而(p1^{c1}+p2^{c2}...pn^{cn})的和不一定要等于n,因为可以单个拆成1,1对lcm没影响。
       即求(p1^{c1}+p2^{c2}...pn^{cn}≤n)的个数。
       于是就可以用背包来解决,设dp[i]表示和为i的数的个数,筛好素数后转移即可。

    代码如下:

    #include<cstdio>
    #include<algorithm>
    #define ll long long
    using namespace std;
    
    const int maxn = 1005;
    int n, mark[maxn], prim[maxn], tot;
    ll ans, dp[maxn];
    
    void prepare(int x) {
    	for (int i = 2; i <= x; ++ i) {
    	  if (!mark[i]) prim[++ tot] = i;
    	  for (int j = 1; j <= tot; ++ j) {
    	  	if (i * prim[j] > x) break;
    	  	mark[i * prim[j]] = 1;
    	  	if (i % prim[j] == 0) break;
    	  }
    	}
    }
    
    int main() {
    	scanf("%d", &n);
    	prepare(n);
    	dp[0] = 1;
    	  for (int i = 1; i <= tot; ++ i)
    	    for (int j = n; j >= prim[i]; -- j)
    	      for (int k = prim[i]; k <= j; k *= prim[i]) dp[j] += dp[j - k];
    	  for (int i = 0; i <= n; ++ i) ans += dp[i];
    	printf("%lld", ans);
    	return 0;
    } 
    
  • 相关阅读:
    移动端测试作业小集合 (6)
    移动端测试——手机常见操作的API (5)
    移动端测试——APP元素信息、事件操作、模拟手势API(4)
    移动端测试——APP元素定位操作 (3)
    移动端测试——App基础操作(2)
    移动端测试基础 (1)
    Python进阶-一切皆对象及type-object-class间的关系
    故障-解决pip安装mysqlclient、gevent报找不到cc或gcc错误问题
    Linux环境上部署Flask
    解决多版本共存时,python/pip等命令失效
  • 原文地址:https://www.cnblogs.com/Gaxc/p/10210790.html
Copyright © 2011-2022 走看看