• LGTB 与序列


    LGTB 有一个长度为N 的序列A,现在他想构造一个新的长度为N 的序列B,使得B 中的任意两个数都
    互质。
    并且他要使ai与bi对应项之差最小
    请输出最小值
    输入
    第一行包含一个数N 代表序列初始长度
    接下来一行包含N 个数A1, A2, …, AN,代表序列A
    对于40% 的数据,1  N  10
    对于100% 的数据,1  N  100, 1  ai  30
    输出
    输出包含一行,代表最小值
    样例
    样例输入样例输出
    51
    6 4 2 8
    3
    样例说明
    样例中B 数组可以为1 5 3 1 8

    考虑到bi最多变成58,如果变成更大的数还不如变成1,而且58之内只有16个素数
    并且可以证明对于两个数a > b,变成的数A >= B
    所以最多只有16个最大的数变成素数,其他的数都会变成1

    所以直接对于前16个数dp,dp[i][j]代表到第i个数,哪些素因子被用过了,花费最少为多少。枚举一个数来转移即可

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<cmath>
     6 using namespace std;
     7 int f[101][(1<<16)],a[101],n,tot,pri[18],inf,ans,zt[101];
     8 bool vis[61];
     9 int abs(int a)
    10 {
    11     if (a<0) return -a;
    12     return a;
    13 }
    14 bool cmp(int a,int b)
    15 {
    16     return a>b;
    17 }
    18 int main()
    19 {
    20     int i,j,k,p,l,x,flag;
    21     cin>>n;
    22     for (i=1; i<=n; i++)
    23     {
    24         scanf("%d",&a[i]);
    25     }
    26     sort(a+1,a+n+1,cmp);
    27     for (i=2; i<=60; i++)
    28         if (vis[i]==0)
    29         {
    30             for (j=2*i; j<=60; j+=i)
    31                 vis[j]=1;
    32         }
    33     for (i=2; i<=58; i++)
    34         if (vis[i]==0)
    35         {
    36             tot++;
    37             pri[tot]=i;
    38         }
    39         for (i=2;i<=60;i++)
    40         {
    41             zt[i]=0;
    42             for (j=1;j<=tot;j++)
    43             if (i%pri[j]==0) 
    44             {
    45                 zt[i]|=(1<<j-1);
    46             }
    47         }
    48     memset(f,127/3,sizeof(f));
    49     inf=f[0][0];
    50     f[0][0]=0;
    51     for (i=1; i<=min(n,16); i++)
    52     {
    53         for (j=0; j<=(1<<16)-1; j++)
    54             if(f[i-1][j]!=inf)
    55             {
    56                 f[i][j]=min(f[i][j],f[i-1][j]+abs(a[i]-1));
    57                 for (k=2;k<=60;k++)
    58                 if ((j&zt[k])==0)
    59                 {
    60                     f[i][j|zt[k]]=min(f[i][j|zt[k]],f[i-1][j]+abs(a[i]-k));
    61                 }
    62                 
    63             }
    64     }
    65     ans=inf;
    66     for (i=0; i<=(1<<16)-1; i++)
    67             ans=min(ans,f[min(n,16)][i]);
    68     for (i=min(n,16)+1;i<=n;i++)
    69             ans+=abs(a[i]-1);
    70     cout<<ans;
    71 }
  • 相关阅读:
    小学四则运算APP 最后阶段
    小学四则运算APP 第三阶段冲刺-第一天
    小学四则运算APP 第二阶段冲刺-第五天
    小学四则运算APP 第二次冲刺 第四天
    小学四则运算APP 第二阶段冲刺-第三天
    小学四则运算APP 第二次冲刺-第二天
    小学四则运算APP 第二个冲刺 第一天
    小学四则运算APP 第一个冲刺 第八天
    小学四则运算APP 第一个冲刺 第七天
    小学四则运算APP 第一个冲刺阶段 第六天
  • 原文地址:https://www.cnblogs.com/Y-E-T-I/p/7723652.html
Copyright © 2020-2023  润新知