[CQOI2016]手机号码(洛谷P4124)

手机号码

数位DP模板题

记忆化搜索:

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#define int long long
int L,R,Maxx[15],dp[15][2][15][2][2][2];
int dfs(int len,bool ok,int last,bool same,bool four,bool eight,bool shangxian)
//剩余的位数,是否已经有三个连续相同的数字,上一个数字,上一个数是否与上上个数字相同,是否有4,是否有8,是否是上限值 {
if(len==0) return (int)ok; if(!shangxian&&dp[len][ok][last][same][four][eight]!=-1) return dp[len][ok][last][same][four][eight]; int M=shangxian?Maxx[len]:9,cnt=0; for(int i=0;i<=M;i++){ if((four&&i==8)||(eight&&i==4)||(len==11&&i==0)) continue; cnt+=dfs(len-1,ok||(same&&last==i),i,last==i,four||i==4,eight||i==8,shangxian&&i==M); } if(!shangxian) dp[len][ok][last][same][four][eight]=cnt; return cnt; } int solve(int x){ int cnt=0; memset(dp,-1,sizeof(dp)); while(x){ Maxx[++cnt]=x%10; x/=10; } return dfs(11,0,-1,0,0,0,1); } #undef int int main() #define int long long { scanf("%lld%lld",&L,&R); int B=solve(L-1); int A=solve(R); printf("%lld\n",A-B); return 0; }

猜你喜欢

转载自www.cnblogs.com/yjkhhh/p/9261597.html