zoukankan      html  css  js  c++  java
  • BZOJ1025: [SCOI2009]游戏

    1025: [SCOI2009]游戏

    Time Limit: 1 Sec  Memory Limit: 162 MB
    Submit: 2029  Solved: 1315
    [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,1 <= N <= 1000

    Output

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

    Sample Input

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

    Sample Output

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

    HINT

     

    Source

     题解:

       置换+DP  

       置换:没学过的还是先去看一下吧,利用置换的知识将题目大意转化为:

          给你一个数n,你可以将他进行整数拆分,然后将这些拆出来的数求LCM

          最后求LCM的种类个数!

       DP:考虑求出质因数,列出dp:F[n][m](用前m个质因数拼出n的方案数);

    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    #define ll long long
    #define ld long double
    #define N 1005
    using namespace std;
    bool vis[N];
    int pri[N],n,tot;
    ll f[N][N];
    int read()
    {
        int x=0,f=1; char ch;
        while (ch=getchar(),ch<'0'||ch>'9') if (ch=='-') f=-1;
        while (x=x*10+ch-'0',ch=getchar(),ch>='0'&&ch<='9');
        return x*f;
    }
    int main()
    {
        n=read();
        for (int i=2; i<=n; i++){
            if (!vis[i]) {++tot; pri[tot]=i;}
            for (int j=1; j<=tot && i*pri[j]<=n; j++)
            {
                vis[i*pri[j]]=1; if (i%pri[j]==0) break;
            }
        } 
        for (int i=1; i<=tot; i++) f[0][i]=1;
        for (int i=0; i<=n; i++) f[i][0]=1;
        for (int j=1; j<=tot; j++){
            for (int i=1; i<=n; i++){
                f[i][j]=f[i][j-1];
                int tmp=pri[j];
                while (i-tmp>=0){
                    f[i][j]+=f[i-tmp][j-1];
                    tmp=tmp*pri[j];
                }
            }
        }
        
        printf("%lld
    ",f[n][tot]);
        return 0;
    }

          

     
  • 相关阅读:
    1093 Count PAT's(25 分)
    1089 Insert or Merge(25 分)
    1088 Rational Arithmetic(20 分)
    1081 Rational Sum(20 分)
    1069 The Black Hole of Numbers(20 分)
    1059 Prime Factors(25 分)
    1050 String Subtraction (20)
    根据生日计算员工年龄
    动态获取当前日期和时间
    对计数结果进行4舍5入
  • 原文地址:https://www.cnblogs.com/HQHQ/p/6036508.html
Copyright © 2011-2022 走看看