bzoj 4521 电话号码

题目大意:

求$[L,R]$中,满足不同时存在4和8且有连续三个一样的个数

思路:

我为什么要记忆化搜索里带-1啊 我可真是个**

直接记忆化搜索记前两位是否有4,8以及是否满足连续

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cstdlib>
 5 #include<cmath>
 6 #include<algorithm>
 7 #include<queue>
 8 #include<vector>
 9 #include<set>
10 #include<map>
11 #define ll long long
12 #define rep(i,s,t) for(int i=(s),i##end=(t);i<=i##end;++i)
13 #define dwn(i,s,t) for(int i=(s),i##end=(t);i>=i##end;--i)
14 #define ren for(int i=fst[x];i;i=nxt[i])
15 #define MAXN 100100
16 using namespace std;
17 inline ll read()
18 {
19     ll x=0,f=1;char ch=getchar();
20     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
21     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
22     return x*f;
23 }
24 ll L,R,f[12][12][10][2][2][2];int g[12],len;
25 int dfs(int m,int l1,int l2,int ok,int v4,int v8,int lim)
26 {
27     if(v4&&v8) return 0;if(!m) return ok;ll res=f[m][l1][l2][ok][v4][v8];
28     if(!lim&&res!=0) return res;if(lim) res=0;int lmt=lim?g[m]:9;
29     rep(i,0,lmt) res+=dfs(m-1,l2,i,ok|(i==l1&&i==l2),v4|(i==4),v8|(i==8),lim&(i==g[m]));
30     if(!lim) f[m][l1][l2][ok][v4][v8]=res;return res;
31 }
32 ll solve(ll x,ll res=0)
33 {
34     memset(f,0,sizeof(f));
35     len=0;while(x) g[++len]=x%10LL,x/=10LL;
36     rep(i,1,g[len]) res+=dfs(len-1,10,i,0,i==4,i==8,i==g[len]);return res;
37 }
38 int main()
39 {
40     L=read(),R=read();
41     if(L!=10000000000LL) printf("%lld",solve(R)-solve(L-1));
42     else printf("%lld",solve(R));
43 }
View Code

 

posted @ 2019-03-19 13:11  jack_yyc  阅读(125)  评论(0编辑  收藏  举报