zoukankan      html  css  js  c++  java
  • Wish-递推DP记数

    链接:https://nanti.jisuanke.com/t/35618

    题意:

    如果一个数大于等于 1010 且任意连续两位都是质数,那么就称之为 Wish 数。当然,第一个 Wish 数是 1111。

    比如 9797,111111,131131,119119 都是 Wish 数,而 1212,136136 则不是。问第 NN 个 Wish 数是多少。

    思路:预处理一下  1 -  9 每个数后面可以跟的能够与它组成两位数字并且为素数的数字。

    dp[ i ] [ j ]  i 的含义是 i 长度为i 的数字,开头为 j 的 wish 数,那么他就可以由 dp [ i - 1] [ 预处理的 g[ j ]  ]转移而来

    需要cnt  [ i ]存储的是 长度为 i 的总数 ,最后根据n 去具体定位那个数,可以先确定是个几位数 。然后从 高位开始确定每一位数字是什么。

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define maxn 123
    vector<int>g[123],ans;
    ll n,cnt[maxn+1],sum,x;
    ll dp[maxn+10][13];
    bool isprime[maxn+10];
    void getprim()
    {
        isprime[0]=isprime[1]=1;
        for(int i=2; i<=sqrt(maxn); i++)
            for(int j=i*i; j<maxn; j+=i)
                isprime[j]=1;
    }
    int main()
    {
        getprim();
        scanf("%lld",&n);
        for(int i=1; i<10; i++)
            for(int j=1; j<10; j++)
                if(isprime[i*10+j]==0)g[i].push_back(j);
        for(int i=1; i<10; i++)g[10].push_back(i);
        for(int i=2; i<50; i++)
            for(int j=1; j<10; j++)
            {
                for(int k=0; k<g[j].size(); k++)
                    dp[i][j]+=(i==2?1:dp[i-1][g[j][k]]);
                cnt[i]+=dp[i][j];
            }
        for(int i=2; i<50; i++)
        {
            if(sum+cnt[i]<n)
                sum+=cnt[i];
            else
            {
                n-=sum;
                x=10;
                for(int k=i; k>=2; k--)
                    for(int u=0; u<g[x].size(); u++)
                    {
                        int v=g[x][u];
                        if(n-dp[k][v]<=0)
                        {
                            ans.push_back(v);
                            x=v;
                            break;
                        }
                        else
                            n-=dp[k][v];
                    }
                ans.push_back(g[x][n-1]);
                break;
            }
        }
        for(int i=0; i<ans.size(); i++)
            printf("%d",ans[i]);
        printf("
    ");
        return 0;
    }
    

      

  • 相关阅读:
    CXF入门案例
    计算python内部数据结构时间效率-源代码
    笨办法学习python-ex41源码加自己注释
    python之random模块
    python之模块、类、对象
    购物车代码
    ql的python学习之路-day1
    数组转置(函数指针,回调函数)
    将一句话按单词逆转
    *一个二级指针的练习(输入一个数,输出对应的月份)
  • 原文地址:https://www.cnblogs.com/SDUTNING/p/10294815.html
Copyright © 2011-2022 走看看