• bjoi 2010 取数游戏 动态规划


    题意:小 C 刚学了辗转相除法,正不亦乐乎,这小 P 又出来捣乱,给小 C 留了个 难题。 给 N 个数,用 a1,a2…an来表示。现在小 P 让小 C 依次取数,第一个数可以 随意取。假使目前取得 aj,下一个数取ak(k>j),则ak必须满足gcd(aj,ak)≥L。 到底要取多少个数呢?自然是越多越好! 不用多说,这不仅是给小 C 的难题,也是给你的难题。

    思路:类似最长上升子序列

    建一个num[1000000]数组 表示当前是x的倍数的数最多能取num[x]个

     1 #include<iostream>
     2 #include<cmath>
     3 #include<cstring>
     4 #include<cstdio>
     5 using namespace std;
     6 #define MAXN 50001
     7 int n,m,top,factor_num;
     8 int a[MAXN];
     9 int factor[1000],prime[1000],p[1000],p_num[1000];
    10 int num[1000001];
    11 bool use[1001];
    12 void find_prime()
    13 {
    14     int i,j;
    15     memset(use,1,sizeof(use));
    16     for(i=2;i<=1000;i++)
    17     if(use[i])
    18         for(j=i*i;j<=1000;j+=i)
    19             use[j]=0;
    20     j=0;
    21     for(i=2;i<=1000;i++)
    22         if(use[i])
    23             prime[++j]=i;
    24     prime[++j]=987654321;
    25 }
    26 void div(int x)
    27 {
    28     top=0;
    29     for(int i=1;prime[i]<=sqrt(x);i++)
    30     {
    31         if(x%prime[i]==0)
    32         {
    33             p[++top]=prime[i];
    34             p_num[top]=0;
    35         }
    36         while(x%prime[i]==0)
    37             p_num[top]++,x=x/prime[i];
    38     }
    39     if(x!=1)
    40     {
    41         p[++top]=x;
    42         p_num[top]=1;
    43     }
    44 }
    45 void dfs(int i,int x)
    46 {
    47     if(i==top+1)
    48     {
    49         factor[++factor_num]=x;
    50         return ;
    51     }
    52     dfs(i+1,x);
    53     for(int j=0;j<p_num[i];j++)
    54     {
    55         x=x*p[i];
    56         dfs(i+1,x);
    57     }
    58 }
    59 int find_answer()
    60 {
    61     int s=0;
    62     for(int i=1;i<=factor_num;i++)
    63         if(factor[i]>=m&&num[factor[i]]>s) s=num[factor[i]];
    64     for(int i=1;i<=factor_num;i++)
    65         if(factor[i]>=m) num[factor[i]]=s+1;
    66     return s+1;
    67 }
    68 int solve()
    69 {
    70     int s=0,i,j,t;
    71     for(i=1;i<=n;i++)
    72     {
    73         div(a[i]);
    74         factor_num=0;
    75         dfs(1,1);
    76         t=find_answer();
    77         if(t>s) s=t;
    78     }
    79     return s;
    80 }
    81 int main()
    82 {
    83     memset(num,0,sizeof(num));
    84     find_prime();
    85     scanf("%d%d",&n,&m);
    86     int i;
    87     for(i=1;i<=n;i++) scanf("%d",a+i);
    88     printf("%d",solve());
    89     return 0;
    90 }
  • 相关阅读:
    JavaScript学习总结--事件冒泡与事件捕获
    JavaScript学习总结5--事件对象
    使用“微信公众号淘客管理工具”10分钟就能搭建淘客返利公众号
    C#实现通过拼多多分享微信公众号实现查询优惠券、佣金比率
    C# 实现生成带二维码的专属微信公众号推广海报
    公众号搭建淘宝、京东、拼多多查券平台
    开始使用Material UI
    Jenkins执行批处理文件失败
    取消Jquery mobile自动省略的文本
    C#调用Win32 api时的内存操作
  • 原文地址:https://www.cnblogs.com/myoi/p/2481313.html
Copyright © 2020-2023  润新知