BZOJ 1025--游戏(DP)

Posted

tags:

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

1025: [SCOI2009]游戏

Time Limit: 1 Sec  Memory Limit: 162 MB
Submit: 2550  Solved: 1664
[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

题目链接:

    http://www.lydsy.com/JudgeOnline/problem.php?id=1025 

Solution

    置换的性质。。

    显然在置换过程中会有几个环,而排数则是每个环大小的公倍数。。

    于是DP一下有多少不同的公因数即可。。

代码

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<iostream>
#define N 200000
#define LL long long
using namespace std;
inline int Read(){
    int x=0,f=1;char ch=getchar();
    while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();}
    while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();}
    return x*f;
}
int n,tot;
LL dp[1005],c[1005],pri[1005];
int main(){
    for(int i=2;i<=1005;i++){
        if(c[i]==0) pri[++tot]=i;
        for(int j=1;j<=tot&&pri[j]*i<=1005;j++){
            c[pri[j]*i]=1;
            if(i%pri[j]==0) break;
        }
    }
    scanf("%d",&n);
    for(int i=0;i<=n;i++) dp[i]=1;
    for(int i=1;i<=tot;i++){
        for(int k=n;k>=pri[i];k--){
            for(int j=pri[i];j<=k;j*=pri[i]){
                dp[k]+=dp[k-j];
            }
        }
    }
    printf("%lld\n",dp[n]);
    return 0;
}

  

  

This passage is made by Iscream-2001.

 

以上是关于BZOJ 1025--游戏(DP)的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ 1025--游戏(DP)

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

bzoj 1025[SCOI2009]游戏 - 背包dp

BZOJ1025 [SCOI2009]游戏 置换群 + 背包dp

bzoj1025SCOI2009游戏dp

[BZOJ 1025] 游戏 置换群 背包DP