zoukankan      html  css  js  c++  java
  • [luogu4161 SCOI2009]游戏 (DP)

    传送门

    Solution

    可以发现实际上是把n分为几个循环节,然后找循环节的(lcm)是这次的排数
    (lcm)必然是一些最高次幂的质数的成积,那么就dp求一下所有情况就好了
    PS:注意并不是必须要等于n小于n都行,因为可以在后面补1而(lcm)不变

    Code

    #include <cmath>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #define Re register
    #define int long long
    #define F(i,a,b) for(Re int i=(a);i<=(b);i++)
    #define R(i,a,b) for(Re int i=(b);i>=(a);i--)
    using namespace std;
    
    inline int read() {
    	int x=0,f=1;char c=getchar();
    	while(!isdigit(c)) {if(c=='-')f=-f;c=getchar();}
    	while(isdigit(c)) x=(x<<1)+(x<<3)+c-48,c=getchar();
    	return x*f;
    }
    
    const int N=1010;
    bool vis[N];
    int n,tot,ans;
    int pri[N],f[N];
    
    void init() {
    	F(i,2,n) {
    		if(!vis[i]) pri[++tot]=i;
    		for(Re int j=1;j<=tot&&i*pri[j]<=n;j++) {
    			vis[i*pri[j]]=1;
    			if(i%pri[j]==0) break; 
    		}
    	}
    }
    
    signed main() {
    	n=read();
    	init();
    //	F(i,1,tot) printf("%d ",pri[i]);cout<<endl;
    	f[0]=1;
    	F(i,1,tot) R(j,0,n) for(Re int k=pri[i];j+k<=n;k*=pri[i]) f[j+k]+=f[j];	
    	F(i,0,n) ans+=f[i];
    	printf("%lld",ans);
    	return 0;
    }
    
  • 相关阅读:
    win中使用curl上传文件报错
    S2-052
    S2-048
    S2-045、S2-046
    S2-033、S2-037
    S2-032
    S2-029
    day12-python之深灰魔法
    day10-11-python基础之字符串
    day09-python基础
  • 原文地址:https://www.cnblogs.com/Menteur-Hxy/p/9737431.html
Copyright © 2011-2022 走看看