zoukankan      html  css  js  c++  java
  • 20181031noip模拟赛T2

    思路:

    这道题是个图论抽象的题目……

    考场上想到了没写对……

    我们发现,f函数转移的方式有两种,要么是代价10的+1,要么是代价1的乘一个质因数

    那么我们就可以将这个抽象为一张图

    每个i向每个i+1连一条边权为10的边

    每个i向每个i*质因子[j]连一条边权为1的边

    跑最短路即可

    跑完最短路就是状压搜索

    加上最优化剪枝和记忆化剪枝即可

    代码:

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #define rii register int i
    #define rij register int j
    #define int long long
    using namespace std;
    int k,dp[100005];
    int ans,sl,ss[10005],sk,s[10005],minx,head[505],cnt,jl[505];
    int fin=2147483647,dis[105];
    struct uio{
        int nxt,to,val;
    }x[10005];
    void add(int from,int to,int val)
    {
        cnt++;
        x[cnt].to=to;
        x[cnt].val=val;
        x[cnt].nxt=head[from];
        head[from]=cnt;
    }
    //void dfs(int p,int q,int dj,int sd)
    //{
    //    if(sd>100)
    //    {
    //        return;
    //    }
    //    if(dj>ans)
    //    {
    //        return;
    //    }
    //    if(q==0)
    //    {
    //        ans=min(ans,dj);
    //        return;
    //    }
    //    dfs(p,(q+1)%p,dj+10,sd+1);
    //    for(rii=1;i<=sl;i++)
    //    {
    //        dfs(p,(q*s[i])%p,dj+1,sd+1);
    //    }
    //}
    void djstl(int wz)
    {
        for(rii=head[wz];i!=0;i=x[i].nxt)
        {
            if(dis[x[i].to]>dis[wz]+x[i].val)
            {
                dis[x[i].to]=dis[wz]+x[i].val;
                djstl(x[i].to);
            }
        }
    }
    void cf(int val)
    {
        cnt=0;
        memset(head,0,sizeof(head));
        sl=0;
        for(rii=2;i<=val;i++)
        {
            if(val%i==0)
            {
                val/=i;
                if(s[sl]!=i)
                {
                    sl++;
                    s[sl]=i;
                    i--;
                }
            }
            if(val==1)
            {
                return;
            }
        }
    }
    int f(int val)
    {
        cnt=0;
        memset(x,0,sizeof(x));
        memset(head,0,sizeof(0));
        memset(dis,0x3f,sizeof(dis));
        int p=0,q=1,ltt=val;
        while(ltt>0)
        {
            p+=ltt%10;
            ltt/=10;
        }
        p+=5;
        ltt=val;
        while(ltt>0)
        {
            q*=ltt%10;
            ltt/=10;
        }
        cf(val);
        q+=233;
        q%=p;
        for(rii=0;i<p;i++)
        {
            for(rij=1;j<=sl;j++)
            {
                add(i,i*s[j]%p,1);
            }
            add(i,(i+1)%p,10);
        }
        dis[q]=0;
        djstl(q);
        return dis[0];
    }
    void cfk(int val)
    {
        sk=0;
        for(rii=2;i<=val;i++)
        {
            if(val%i==0)
            {
                val/=i;
                if(ss[sk]!=i)
                {
                    sk++;
                    ss[sk]=i;
                    i--;
                }
            }
            if(val==1)
            {
                return;
            }
        }
    }
    inline int gtv(int v)
    {
        int kkk=1,cnt=0;
        while(v!=0)
        {
            cnt++;
            if(v%2==1)
            {
                kkk*=ss[cnt];
            }
            v/=2;
        }
        return kkk;
    }
    void kfs(int zt,int dj)
    {
        if(dp[zt]>dj)
        {
            dp[zt]=dj;
        }
        else
        {
            return;
        }
        if(dj>=fin)
        {
            return;
        }
        if(dj<fin&&zt==(1<<sk)-1)
        {
            fin=dj;
            return;
        }
        for(rii=1;i<=(1<<sk)-1;i++)
        {
            if((zt&i)==0)
            {
                kfs(zt|i,dj+f(gtv(i)));
            } 
        }
    }
    signed main()
    {
        freopen("k.in","r",stdin);
        freopen("k.out","w",stdout);
        memset(dp,0x3f,sizeof(dp));
        cin>>k;
        cfk(k);
        if(sk==0)
        {
            cout<<f(k);
            return 0;
        }
        fin=f(k);
        kfs(0,0);
        cout<<fin;
    }
  • 相关阅读:
    关于group by【转载】
    Hive常用命令
    Hive学习笔记【转载】
    Java多线程的join()
    Java多线程编程
    把struts2-convention-plugin丢进太平洋
    关于unsigned int和int的加法
    C#高级参数out,ref,params
    Winform禁止程序多开 &&禁止多开且第二次激活第一次窗口
    .NET对象与Windows句柄(三):句柄泄露实例分析
  • 原文地址:https://www.cnblogs.com/ztz11/p/9885574.html
Copyright © 2011-2022 走看看