码迷,mamicode.com
首页 > 其他好文 > 详细

BZOJ 1025 [SCOI2009]游戏

时间:2017-09-19 00:15:21      阅读:211      评论:0      收藏:0      [点我收藏+]

标签:bsp   printf   ace   ret   循环   iostream   turn   print   style   

之前找LLJ大佬推荐水题的时候让我做这个,然后不出意料的我不会。

日常抄题解。

手玩几组数据发现它N个数可以分成多个组,每个组为一个循环,他们的LCM就是最后的层数。

预处理出n以内的所有质数,我们可以把n分解成p1^a1+p2^a2+p3^a3...不同的p之间的lcm数可以直接相乘,我们用dp递推地算答案,dp[i][j表示前i个质数和为j的lcm数,然后就可以DP了。

最后统计答案要把0~n的dp[p[0]][i]加起来,因为每个数可以单成一组。

技术分享
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<queue>
#include<vector>
typedef long long LL;
using namespace std;
const int maxn=1000+299;
LL n,p[maxn],bo[maxn],dp[maxn][maxn];
int main()
{
    //freopen(".in","r",stdin);
    //freopen(".out","w",stdout);
    scanf("%lld",&n);
    for(int i=2;i<=n;i++) {
        if(!bo[i]) p[++p[0]]=i;
        for(int j=1;j<=p[0]&&p[j]*i<=n;j++) {
            bo[i*p[j]]=1;
            if(i%p[j]==0) break;
        }
     }
     dp[0][0]=1;
     for(int i=1;i<=p[0];i++){
         for(int j=0;j<=n;j++) {
             dp[i][j]+=dp[i-1][j];
             for(int k=p[i];k<=j;k*=p[i]) {
                 {
                     dp[i][j]+=dp[i-1][j-k];
                 }
             }
          }
    }
    LL ans=0;
    for(int i=0;i<=n;i++)
        ans+=dp[p[0]][i];
    printf("%lld\n",ans);
    return 0;
}
View Code

 

BZOJ 1025 [SCOI2009]游戏

标签:bsp   printf   ace   ret   循环   iostream   turn   print   style   

原文地址:http://www.cnblogs.com/Achenchen/p/7545693.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!