zoukankan      html  css  js  c++  java
  • Luogu p3413(数位dp)

    传送门

    题意:

    给你一个区间([l,r]),让你求着个区间中,存在长度至少为(2)的回文子串的数的个数。

    分析:

    因为所要求的区间相当的大,因此我们不妨从它的数位入手进行(dp)

    根据萌数的性质,倘若要满足一个长度为(len)的字符串是萌数,那么这个串只需至少包含一个长度为(2)(对应偶回文),或者至少包含一个长度为(3)(对应奇回文)的回文串即可。至此,我们将题目进行了转化,即:如果一个串包含有一个长度为(2)或者长度为(3)的字符串,那么这个数就是萌数。

    因此我们只需要讨论一个串的当前位(pos),它的前一位(pre1),以及它的前两位(pre2)即可。因此我们可以设计一个(dp[pos][pre1][pre2])(dp)数组。但是我们发现,如果这样去设计状态的话,部分合法以及非法状态会发生重叠:如果当前的枚举到的状态是(dp[1][2][3])的状态(即代表枚举到的子串的状态位(123))。此时的这个状态中,合法状态(33123)以及非法状态(45123)将会发生重叠。因此为了防止这种情况,我们考虑再开多一维判断是否在之前是否已经合法子串。故我们可以设计(dp[pos][pre1][pre2][exist])代表,当前位置位(pos),前一位为(pre1),前两位为(pre2),且之前存在/不存在子串的方案数。

    而我们发现,当设计了(exist)这个状态之后,我们就不需要记录前两位(pre2)的信息了,因此我们只需要开一个三维的(dp)数组(dp[pos][pre1][exist])即可。

    而把状态设计好之后,我们就只需要直接套用记忆化搜索的数位dp的板子就可以很简单的结局了。

    代码:

    #include <bits/stdc++.h>
    #define maxn 1005
    using namespace std;
    typedef long long ll;
    ll dp[maxn][15][2];
    char L[maxn],R[maxn];
    int bit[maxn],len;
    const int mod=1e9+7;
    ll dfs(int pos,int pre1,int pre2,int exist,int lead,int limit){
        if(pos==0) return exist;
        if(pre1!=-1&&pre2!=-1&&!lead&&!limit&&dp[pos][pre1][exist]!=-1)
            return dp[pos][pre1][exist];
        int up=limit?bit[pos]:9;
        ll res=0;
        for(int i=0;i<=up;i++){
            int p=(lead&&i==0)?-1:i;
            res+=dfs(pos-1,p,pre1,exist|(p!=-1 && (p==pre1||p==pre2)),p==-1,limit&&(p==up));
            res%=mod;
        }
        if(pre1!=-1&&pre2!=-1&&!lead&&!limit) dp[pos][pre1][exist]=res;
        return res;
    }
    ll solve(char *str,bool sub){
        len=strlen(str);
        for(int i=1;i<=len;i++)
            bit[len-i+1]=str[i-1]-'0';
        if(sub){
            int now=1;
            while(bit[now]==0) bit[now++]=9;
            bit[now]--;
            while(!bit[len] && len) len--;
        }
        memset(dp,-1,sizeof(dp));
        return dfs(len,-1,-1,0,1,1);
    }
    int main()
    {
        scanf("%s%s",L,R);
        printf("%lld",((solve(R,0)-solve(L,1))%mod+mod)%mod);
        return 0;
    }
    
  • 相关阅读:
    win7网络共享原来如此简单,WiFi共享精灵开启半天都弱爆了!
    JQUERY UI Datepicker Demo
    Official online document, install svn server in centOS
    JAVE not work in linux
    AMR 转mp3 失败
    XD, XR, DR 股票
    Linux 下MySql 重置密码
    Difinition Of Done
    Apache, Tomcat, JK Configuration Example
    Linux 安装tomcat
  • 原文地址:https://www.cnblogs.com/Chen-Jr/p/11287466.html
Copyright © 2011-2022 走看看