手機號碼
數位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; }