洛谷 3413 萌数
Posted ovo
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了洛谷 3413 萌数相关的知识,希望对你有一定的参考价值。
Description
辣鸡蒟蒻SOL是一个傻逼,他居然觉得数很萌!
好在在他眼里,并不是所有数都是萌的。只有满足“存在长度至少为2的回文子串”的数是萌的——也就是说,101是萌的,因为101本身就是一个回文数;110是萌的,因为包含回文子串11;但是102不是萌的,1201也不是萌的。
现在SOL想知道从l到r的所有整数中有多少个萌数。
由于答案可能很大,所以只需要输出答案对1000000007(10^9+7)的余数。
Putin
输入包含仅1行,包含两个整数:l、r。
Putout
输出仅1行,包含一个整数,即为答案。
Sample
输入样例#1:
1 100
输出样例#1:
10
输入样例#2:
100 1000
输出样例#2:
253
Hints
记n为r在10进制下的位数。
对于10%的数据,n <= 3。
对于30%的数据,n <= 6。
对于60%的数据,n <= 9。
对于全部的数据,n <= 1000,l < r。
Solution
数位dp
dp[i][j][k][l]表示到第i位,上一位为j,上上位为k,目前是(不是)萌数的萌数个数
因为前导0相等不算回文,所以要判前导0
l,r比较大,l-1的话很麻烦,可以把l,r同时带入或者先算出num(r)-num(l),再判断l是否是一个萌数
#include<algorithm> #include<iostream> #include<cstring> #include<cstdlib> #include<cstdio> #define nn 1011 #define lo long long #define mod 1000000007 using namespace std; lo dp[nn][11][11][2]; char l[nn],r[nn]; int a[nn]; int read() { int ans=0,f=1;char ch=getchar(); while(!isdigit(ch)) {if(ch==‘-‘) f=-1;ch=getchar();} while(isdigit(ch)) {ans=ans*10+ch-‘0‘;ch=getchar();} return ans*f; } lo dfs(int w,int pre,int ago,bool lim,bool cute,bool fir) //位数,上一位,上上位,限制?,萌数?,前导0 { if(w<1) return cute; if(!lim&&dp[w][pre][ago][cute]>-1) return dp[w][pre][ago][cute]; lo ans=0; int o=lim? a[w]:9; for(int i=0;i<=o;i++) ans=(ans+dfs(w-1,fir&&i==0? -1:i,pre,lim&&i==a[w],cute||i==pre||i==ago,fir&&i==0))%mod; if(!lim) dp[w][pre][ago][cute]=ans; return ans; } lo solve(char *x) { int w=strlen(x); for(int i=0;i<w;i++) a[w-i]=x[i]-‘0‘; return dfs(w,-1,-1,1,0,1); } int main() { lo ans=0; scanf("%s%s",l,r); memset(dp,-1,sizeof(dp)); ans=(solve(r)-solve(l)+mod)%mod; int ll=strlen(l); for(int i=0;i<ll;i++) if(l[i]==l[i+1]||l[i]==l[i+2]) { ans=(ans+1)%mod; break; } printf("%lld",ans); }
以上是关于洛谷 3413 萌数的主要内容,如果未能解决你的问题,请参考以下文章