zoukankan      html  css  js  c++  java
  • LUOGU P3413 SAC#1

    传送门

    解题思路

      首先这道题如果有两个以上长度的回文串,那么就一定有三个或两个的回文串,所以只需要记录一下上一位和上上位填的数字就行了。数位(dp),用记忆化搜索来实现。设(f[i][j][k][0/1])表示填到了第(i)位,上上位数字为(j),上一位数字为(k)(0/1)表示有没有出现过回文串的方案数。(dfs)里在套路的传一个这一位有没有限制和前导0,细节还是比较多的。

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    
    using namespace std;
    const int MAXN = 1005;
    const int MOD = 1e9+7;
    typedef long long LL;
    
    string l,r;
    int cnt,num[MAXN];
    LL f[MAXN][15][15][2];
    
    LL dfs(int x,int pre,int pree,bool lim,bool zero,int exist){
    	if(x==0) return exist;
    	int Max=lim?num[x]:9,p;LL sum=0;
    	if(f[x][pre][pree][exist]!=-1 && !lim && !zero) return f[x][pre][pree][exist];
    	for(int i=0;i<=Max;i++){
    		p=(zero&&i==0)?-1:i;
    		int A=pre,B=pree;
    		sum+=dfs(x-1,pree,p,(lim&&(p==num[x])),(p==-1),exist|(p!=-1 && (pree==p || pre==p)));		
    		sum%=MOD;
    	}
    	if(!zero && !lim) f[x][pre][pree][exist]=sum;
    	return sum;
    }
    
    LL solve(string s,bool sub){
    	cnt=s.length();
    	for(int i=1;i<=cnt;i++)
    		num[cnt-i+1]=s[i-1]-'0';
    	if(sub){
    		int now=1;
    		while(num[now]==0) num[now++]=9;
    		num[now]--;
    		while(!num[cnt] && cnt) cnt--;
    	}
    	memset(f,-1,sizeof(f));
    	return dfs(cnt,-1,-1,1,1,0);
    }
    
    int main(){
    	cin>>l>>r;
    	printf("%lld",((solve(r,0)-solve(l,1))%MOD+MOD)%MOD);
    	return 0;
    }
    
  • 相关阅读:
    input.file上传图片| FileReader h5新特性
    lua的luasocket程序
    nginx的proxy_set_header
    lua的table.sort
    lua的深拷贝和浅拷贝
    nginx的location匹配
    kong后台接口
    一些程序和工具
    lua的模式匹配
    php的一些语法
  • 原文地址:https://www.cnblogs.com/sdfzsyq/p/9813442.html
Copyright © 2011-2022 走看看