typedef long long LL ; const int Max_N = 20 ; LL dp[Max_N][Max_N] ; int bit[Max_N] ; LL DP(int pos , int pre , int isend){ if(pos == -1) return 1 ; if(!isend && dp[pos][pre] != -1) return dp[pos][pre] ; int d = isend ? bit[pos] : 9 ; LL ans = 0 ; for(int i = 0 ; i <= d ; i++){ if(i == 4) continue ; if(pre == 6 && i == 2) continue ; ans += DP(pos-1 , i , isend && i==d) ; } if(!isend) dp[pos][pre] = ans ; return ans ; } LL Ans(LL x){ int Len = 0 ; while(x){ bit[Len++] = x % 10 ; x /= 10 ; } return DP(Len-1 , 0 , 1) ; } int main(){ memset(dp , -1 , sizeof(dp)) ; LL l , r ; while(cin>>l>>r){ if(l == 0 && r == 0) break ; cout<< Ans(r) - Ans(l-1) <<endl ; } return 0 ; }
法1 : n+1 - 不含49 。
const int Max_N = 20 ; LL dp[Max_N][10] ; int bit[Max_N] ; LL DP(int pos , int pre , int isend){ if(pos == -1) return 1 ; if(!isend && dp[pos][pre] != -1) return dp[pos][pre] ; LL ans = 0 ; int d = isend ? bit[pos] : 9 ; for(int i = 0 ; i <= d ; i++){ if(pre == 4 && i == 9) continue ; ans += DP(pos-1 , i , isend && i == d) ; } if(!isend) dp[pos][pre] = ans ; return ans ; } LL Ans(LL x){ int Len = 0 ; while(x){ bit[Len++] = x % 10 ; x /= 10 ; } return DP(Len-1 , 0 , 1) ; } int main(){ memset(dp , -1 , sizeof(dp)) ; LL n ; int t ; cin>>t ; while(t--){ cin>>n ; cout<< n + 1 - Ans(n) << endl ; } return 0 ; }
const int Max_N = 20 ; LL dp[Max_N][2][10] ; int bit[Max_N] ; LL DP(int pos , int have , int pre , int isend){ if(pos == -1) return have ; if(!isend && dp[pos][have][pre] != -1) return dp[pos][have][pre] ; LL ans = 0 ; int d = isend ? bit[pos] : 9 ; for(int i = 0 ; i <= d ; i++){ if(pre == 4 && i == 9) ans += DP(pos-1 , 1 , i , isend && i==d) ; else ans += DP(pos-1 , have ,i , isend && i == d) ; } if(!isend) dp[pos][have][pre] = ans ; return ans ; } LL Ans(LL x){ int Len = 0 ; while(x){ bit[Len++] = x % 10 ; x /= 10 ; } return DP(Len-1 , 0 , 0 , 1) ; } int main(){ memset(dp , -1 , sizeof(dp)) ; LL n ; int t ; cin>>t ; while(t--){ cin>>n ; cout<< Ans(n) << endl ; } return 0 ; }
const int Max_N = 20 ; LL dp[Max_N][2][10][13] ; int bit[Max_N] ; LL DP(int pos , int have , int pre , int sum , int isend){ if(pos == -1) return have && sum == 0 ; if(!isend && dp[pos][have][pre][sum] != -1) return dp[pos][have][pre][sum] ; LL ans = 0 ; int d = isend ? bit[pos] : 9 ; for(int i = 0 ; i <= d ; i++){ if(pre == 1 && i == 3) ans += DP(pos-1 , 1 , i , (sum*10+i) %13 , isend && i==d) ; else ans += DP(pos-1 , have ,i , (sum*10+i) %13 , isend && i==d) ; } if(!isend) dp[pos][have][pre][sum] = ans ; return ans ; } LL Ans(LL x){ int Len = 0 ; while(x){ bit[Len++] = x % 10 ; x /= 10 ; } return DP(Len-1 , 0 , 0 , 0 , 1) ; } int main(){ memset(dp , -1 , sizeof(dp)) ; LL n ; while(cin>>n){ cout<< Ans(n) << endl ; } return 0 ; }
LL DP(int pos , int one , int isend){ if(pos == -1) return (LL)one ; if(!isend && dp[pos][one] != -1) return dp[pos][one] ; LL ans = 0 ; int d = isend ? bit[pos] : 9 ; for(int i = 0 ; i <= d ; i++) ans += DP(pos-1 , one + (i==1) , isend&&i==d) ; if(!isend) dp[pos][one] = ans ; return ans ; }
const int Max_N = 10008 ; int dp[10][Max_N] ; int bit[10] ; int f(int x){ int s = 0 , i = 0 ; while(x){ s += (x%10) * (1<<i) ; i++ ; x /= 10 ; } return s ; } int DP(int pos , int num , int isend){ if(pos == -1) return num >= 0 ; if(num < 0) return 0 ; if(!isend && dp[pos][num] != -1) return dp[pos][num] ; int d = isend? bit[pos] : 9 ; int ans = 0 ; for(int i = 0 ; i <= d ; i++){ ans += DP(pos-1 , num - i*(1<<pos) , isend && i==d) ; } if(!isend) dp[pos][num] = ans ; return ans ; } int Ans(int A , int B){ int i , Len = 0 ; while(B){ bit[Len++] = B%10 ; B /= 10 ; } return DP(Len-1 , f(A) , 1) ; } int main(){ int cas , T , A , B ; memset(dp , -1 , sizeof(dp)) ; cin>>T ; for(cas = 1 ; cas <= T ; cas++){ scanf("%d%d" ,&A ,&B) ; printf("Case #%d: %d\n" , cas , Ans(A , B)) ; } return 0 ; }
const int Max_N = 20 ; LL dp[Max_N][Max_N][2000] ; int bit[Max_N] ; LL DP(int pos , int center , int sum , int isend){ if(pos == -1) return sum == 0 ; if(sum < 0) return 0 ; if(!isend && dp[pos][center][sum] != -1) return dp[pos][center][sum] ; int d = isend ? bit[pos] : 9 ; LL ans = 0 ; for(LL i = 0 ; i <= d ; i++) ans += DP(pos-1 , center , sum+i*(pos-center) , isend && i==d) ; if(!isend) dp[pos][center][sum] = ans ; return ans ; } LL Ans(LL x){ int Len = 0 ; while(x){ bit[Len++] = x%10 ; x /= 10 ; } LL ans = 0 ; for(int center = 0 ; center < Len ; center++) //枚举支点 ans += DP(Len-1 , center , 0 , 1) ; return ans - (Len-1) ; } int main(){ memset(dp , -1 ,sizeof(dp)) ; int t ; LL l , r ; cin>>t ; while(t--){ scanf("%lld%lld" ,&l ,&r) ; printf("%lld\n" ,Ans(r) - Ans(l-1)) ; } return 0 ; }
关键之处,降维。
const int Max_N = 20 ; LL dp[Max_N][2520][50] ; int bit[Max_N] ; int Maxlcm ; int gcd(int x , int y){ return y == 0 ? x : gcd(y , x%y) ; } int lcm(int x , int y){ return x / gcd(x ,y) * y ; } map<int , int>id , _hash ; LL DP(int pos , int sum , int lcmid , int isend){ if(pos == -1) return sum % id[lcmid] == 0 ; if(!isend && dp[pos][sum][lcmid] != -1) return dp[pos][sum][lcmid] ; int d = isend ? bit[pos] : 9 ; LL ans = 0 ; for(int i = 0 ; i <= d ; i++){ if(i == 0) ans += DP(pos-1 , sum*10%Maxlcm , lcmid , isend && i==d) ; else ans += DP(pos-1 , (sum*10+i)%Maxlcm , _hash[lcm(id[lcmid] ,i)] , isend && i==d) ; } if(!isend) dp[pos][sum][lcmid] = ans ; return ans ; } LL Ans(LL x){ int Len = 0 ; while(x){ bit[Len++] = x%10 ; x /= 10 ; } return DP(Len-1 , 0 , 0 , 1) ; } int main(){ int indx = 0 ; Maxlcm = 1 ; for(int i = 1 ; i <= 9 ; i++) Maxlcm = lcm(Maxlcm , i) ; id.clear() ; _hash.clear() ; for(int i = 1 ; i <= Maxlcm ; i++){ if(Maxlcm % i == 0){ _hash[i] = indx ; id[indx++] = i ; } } memset(dp , -1 , sizeof(dp)) ; int t ; LL l , r ; cin>>t ; while(t--){ cin>>l>>r ; cout<< Ans(r) - Ans(l-1) <<endl ; } return 0 ; }
const int Max_N = 12 ; int dp[Max_N][Max_N][Max_N] ; int bit[Max_N] ; int DP(int pos , int id , int pre , int isend){ if(pos == -1) return 1; if(!isend && dp[pos][id][pre] != -1) return dp[pos][id][pre] ; int ans = 0 ; int d = isend ? bit[pos] : 9 ; if(id&1){ for(int i = pre ; i <= d ; i++) ans += DP(pos-1 , id+1 , i , isend&&i==d) ; } else{ for(int i = 0 ; i <= min(pre , d) ; i++) ans += DP(pos-1 , id+1 , i , isend&&i==d) ; } if(!isend) dp[pos][id][pre] = ans ; return ans ; } int Ans(int x){ int Len = 0 ; while(x){ bit[Len++] = x % 10 ; x /= 10 ; } return DP(Len-1 , 0 , 9 , 1) ; } int main(){ memset(dp , -1 , sizeof(dp)) ; int i , t , l ,r ; cin>>t ; while(t--){ scanf("%d%d" ,&l ,&r) ; printf("%d\n" , Ans(r) - Ans(l-1)) ; } return 0 ; }
LL DP(int pos , int pre , bool islead , int isend){ if(pos == -1) return 1 ; if(!isend && dp[pos][pre] != -1) return dp[pos][pre] ; LL ans = 0 ; int d = isend ? bit[pos] : 9 ; for(int i = 0 ; i <= d ; i++){ if(islead && i==0) ans += DP(pos-1 , 10 , 1 , isend&&i==d) ; else{ if(pre == 10) ans += DP(pos-1 , i , 0 , isend&&i==d) ; else{ if(abs(i-pre) <= 1) continue ; ans += DP(pos-1 , i , 0 , isend&&i==d) ; } } } if(!isend) dp[pos][pre] = ans ; return ans ; } LL Ans(LL x){ int Len = 0 ; while(x){ bit[Len++] = x % 10 ; x /= 10 ; } return DP(Len-1 , 10 , 1 , 1) ; }
int DP(int pos , int prefixsum , int mod , int res , int isend){ if(pos == -1){ if(prefixsum == 0 || prefixsum != mod) return 0 ; return res == 0 ; } if(!isend && dp[pos][prefixsum][mod][res] != -1) return dp[pos][prefixsum][mod][res] ; int ans = 0 ; int d = isend ? bit[pos] : 9 ; for(int i = 0 ; i <= d ; i++) ans += DP(pos-1 , prefixsum+i , mod , (res*10+i) % mod , isend&&i==d) ; if(!isend) dp[pos][prefixsum][mod][res] = ans ; return ans ; } int Ans(int x){ int Len = 0 , ans = 0 ; while(x){ bit[Len++] = x % 10 ; x /= 10 ; } int d = min(81 , 9*Len) ; for(int i = 1 ; i <= d ; i++) ans += DP(Len-1 , 0 , i , 0 , 1) ; return ans ; }
LL DP(int pos , int sum , int b , int isend){ if(pos == -1) return sum == k ; if(sum > k) return 0 ; if(!isend && dp[pos][sum][b] != -1) return dp[pos][sum][b] ; LL ans = 0 ; int t = isend ? min(1 ,bit[pos]) : 1 ; for(int i = 0 ; i <= t ; i++) ans += DP(pos-1 , sum + (i>0? 1 : 0) , b , isend&&i==bit[pos]) ;//i==bit[pos] if(!isend) dp[pos][sum][b] = ans ; return ans ; }