• 质数和分解


     思路

    首先很显然预处理出200以内的质数表

    由于每个数字可以选无数次,可以类比完全背包,最外层枚举当前放哪个质数,内层按照完全背包的顺序枚举,在循环过程中每次按照顺序考虑放哪个质数(放完之后就不再重复考虑,所以自然就是没有重复的)。

    一定要注意,初始化 dp[0] = 1,不能初始化成每个dp[prime(表示一个质数)] = 1,因为会重复考虑。

    转移的时候由于方案数根据加法原理可得转移:dp[j] += dp[j - prime[i] ]  ;

    代码

    #include<bits/stdc++.h>
    using namespace std;
    int prime[105],cnt=1;
    int n;
    int dp[205];
    bool vis[205];
    void pre()
    {
        prime[1]=2;
        vis[2]=1;
        for(int i=3;i<=201;i++)
        {    
            int sq=sqrt(i),flag=0; 
            for(int j=2;j<=sq;j++)
            {
                if(i%j==0) 
                {
                    flag=1;
                    break;
                }
            }
            if(!flag) prime[++cnt]=i,vis[i]=1;
        }
    }
    /*这部分没用
    int tr(int p){ int i; for(i=2;i<=p;i++) for(int j=2;j<=p/i;j++) vis[i*j]=1; } int dfs(int now) { if(now==0) return 0; if(dp[now]&&dp[now]!=1) return dp[now]; for(int i=1;i<=cnt&&prime[i]<=now;i++) dp[now]+=dfs(now-prime[i]); return dp[now]; }
    */
    int main() { pre(); while(scanf("%d",&n)!=EOF) { memset(dp,0,sizeof(dp)); dp[0]=1; for(int i=1;i<=cnt&&prime[i]<=n;i++) { for(int j=prime[i];j<=n;j++) dp[j]+=dp[j-prime[i]]; } printf("%d ",dp[n]); } return 0; }
  • 相关阅读:
    软工人日常
    11.5
    11.4
    11.3
    11.2阅读笔记
    11.1阅读笔记
    10.31 异常
    10.30动手动脑
    10.29
    10.28
  • 原文地址:https://www.cnblogs.com/conprour/p/14825895.html
Copyright © 2020-2023  润新知