zoukankan      html  css  js  c++  java
  • luogu P4161 [SCOI2009]游戏

    传送门

    我们发现整个大置换中,会由若干形如((a_1 ightarrow a_2,a_2 ightarrow a_3,...a_{n-1} ightarrow a_n,a_n ightarrow a_1))的循环置换组成,记某个循环置换中元素个数为(m_i)而整个置换的循环节大小为(lcm(m_1,m_2,...)),那么问题转化成把一个数(n)拆成若干整数之和,问拆出来的整数的(lcm)有多少种

    ([1,n])的质数筛出来,然后dfs,从前往后考虑质数(p_i),每次从剩余的数中减去({p_i}^k),假设某个时刻表示的数为(s),那么减去({p_i}^k)后就能表示(s*{p_i}^k),这样子计算是不重不漏的,但是无法通过此题(方案数为(long long)级别)

    考虑dp,设(f_i)(n=i)时的答案,然后依次枚举质数,因为当前考虑的质数之前没考虑,所以(f_i)可以从(f_{i-p_j},f_{i-{p_j}^2},f_{i-{p_j}^3}...)转移过来,这其实就是个背包

    详见代码

    #include<bits/stdc++.h>
    #define LL long long
    #define il inline
    #define re register
    #define db double
    #define eps (1e-5)
    
    using namespace std;
    il LL rd()
    {
        LL x=0,w=1;char ch=0;
        while(ch<'0'||ch>'9') {if(ch=='-') w=-1;ch=getchar();}
        while(ch>='0'&&ch<='9') {x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
        return x*w;
    }
    int prm[200],tt,n;
    char vis[1010];
    il void init()
    {
      for(int i=2;i<=n;i++)
        {
          if(!vis[i]) prm[++tt]=i;
          for(int j=1;j<=tt&&i*prm[j]<=n;j++)
            {
              vis[i*prm[j]]=true;
              if(i%prm[j]==0) break;
            }
        }
    }
    LL f[1010];
    /*void dfs(int o,int s)
    {
      if(o>tt||s<prm[o]) return;
      dfs(o+1,s);
      int xx=prm[o];
      while(s>=xx)
        {
          ++ans;
          dfs(o+1,s-xx);
          xx*=prm[o];
        }
    }*/
    
    int main()
    {
      n=rd();
      init();
      for(int i=0;i<=n;i++) f[i]=1;
      for(int i=1;i<=tt;i++)
        for(int j=n;j>=0;j--)
          for(int k=prm[i];j-k>=0;k*=prm[i])
            f[j]+=f[j-k];
      printf("%lld
    ",f[n]);
      return 0;
    }
    
  • 相关阅读:
    获取Spring项目配置文件元素
    MyEclipse安装插件的几种方法
    排序-->桶排序
    排序-->冒泡排序
    排序-->选择排序
    排序-->插入排序
    约瑟夫问题----(数组+list)实现
    约瑟夫问题--->环形链表
    py---pycharm快捷键
    双向链表--简单的增删改查
  • 原文地址:https://www.cnblogs.com/smyjr/p/9807151.html
Copyright © 2011-2022 走看看