• 百度之星复赛T5&&hdu6148


    Problem Description

    众所周知,度度熊非常喜欢数字。

    它最近发明了一种新的数字:Valley Number,像山谷一样的数字。

    当一个数字,从左到右依次看过去数字没有出现先递增接着递减的“山峰”现象,就被称作 Valley Number。它可以递增,也可以递减,还可以先递减再递增。在递增或递减的过程中可以出现相等的情况。

    比如,1,10,12,212,32122都是 Valley Number。

    121,12331,21212则不是。

    度度熊想知道不大于N的Valley Number数有多少。

    注意,前导0是不合法的。

    Input

    第一行为T,表示输入数据组数。

    每组数据包含一个数N。

    ● 1≤T≤200

    ● 1≤length(N)≤100

    Output

    对每组数据输出不大于N的Valley Number个数,结果对 1 000 000 007 取模。

    Sample input
    3
    3
    14
    120
    Sample Output
    3
    14
    119
    ——————————————————————————————
    一道很明显的数位dp 然而写挂了很多次QAQ
    f【i】【j】【k】【l】
    表示考虑到第i位 这一位为j 此时是否开始上升 以及前l-1为是否和n(原数)相等
    转移过程看代码吧QAQ 比较难讲 自己研究研究咯
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    using namespace std;
    const int mod=1e9+7,M=157;
    int read(){
        int ans=0,f=1,c=getchar();
        while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
        while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
        return ans*f;
    }
    int T,len,ans,h[M],f[M][15][2][2];
    char s[M];
    int calculate(int k){
        memset(f,0,sizeof(f));
        f[0][9][0][1]=1;
        for(int i=1;i<=k;i++){
            int now=s[i]-'0';
            for(int x=0;x<=9;x++){
                for(int y=(i==1)?1:0;y<=9;y++){
                    for(int z=0;z<2;z++){
                        if(z&&y>now) continue;
                        int nowf=(z&&y==now);
                        if(x>=y){
                            if(x==y) f[i][y][1][nowf]=(f[i][y][1][nowf]+f[i-1][x][1][z])%mod;
                            f[i][y][0][nowf]=(f[i][y][0][nowf]+f[i-1][x][0][z])%mod;
                        }
                        else{
                            f[i][y][1][nowf]=(f[i][y][1][nowf]+f[i-1][x][1][z])%mod;
                            f[i][y][1][nowf]=(f[i][y][1][nowf]+f[i-1][x][0][z])%mod;
                        }
                    }
                }
            }
        }
        int sum=0;
        for(int x=0;x<=9;x++) for(int y=0;y<2;y++) for(int z=0;z<2;z++) sum=(sum+f[k][x][y][z])%mod;
        return sum;
    }
    void prepare(){
        for(int i=1;i<=100;i++) s[i]='9';
        for(int i=1;i<=100;i++) h[i]=calculate(i);
    }
    int main()
    {
        prepare();
        T=read();
        while(T--){
            ans=0;
            scanf("%s",s+1); len=strlen(s+1);    
            for(int i=1;i<len;i++) ans=(ans+h[i])%mod;
            ans=(ans+calculate(len))%mod;
            printf("%d
    ",ans);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    木马后门入侵与RKHunter,ClamAV检测工具
    Jenkins环境搭建
    Mha-Atlas-MySQL高可用
    JAVA企业级应用服务器之TOMCAT实战
    Keepalived高可用集群
    scp ssh-key连接原理
    jumpserver跳板机搭建
    DNS域名解析服务器
    DHCP服务
    Keepalived高可用集群
  • 原文地址:https://www.cnblogs.com/lyzuikeai/p/7392026.html
Copyright © 2020-2023  润新知