Use this to learn the idea, then write your own version.
123 45class Solution {6public:7 long long totalWaviness(long long num1, long long num2) {8 const auto& count = [&](long long x) {9 auto encode = [&](int i, int prev, int prev2, bool zero, bool tight) {10 long long key = i;11 key = key * (10 + 1) + (prev + 1);12 key = key * (10 + 1) + (prev2 + 1);13 key = key * 2 + (zero ? 1 : 0);14 key = key * 2 + (tight ? 1 : 0);15 return key;16 };17 18 const auto& s = to_string(x);19 vector<pair<long long, long long>> lookup(size(s) * (10 + 1) * (10 + 1) * 2 * 2, {-1, -1});20 const auto dp = [&](this auto&& dp, int i, int prev, int prev2, bool zero, bool tight) -> pair<long long, long long> {21 if (i == size(s)) {22 return {1, 0};23 }24 long long key = encode(i, prev, prev2, zero, tight);25 if (lookup[key].first == -1) {26 long long cnt = 0, w = 0;27 const auto& mx = tight ? s[i] - '0' : 9;28 for (int d = 0; d <= mx; ++d) {29 const auto& new_tight = tight && (d == s[i] - '0');30 const auto& new_zero = zero && (d == 0);31 const auto& new_prev2 = prev;32 const auto& new_prev = !new_zero ? d : -1;33 const auto& [new_cnt, nw] = dp(i + 1, new_prev, new_prev2, new_zero, new_tight);34 cnt += new_cnt;35 if (!zero && prev2 != -1 && ((prev2 < prev && prev > d) || (prev2 > prev && prev < d))) {36 w += new_cnt;37 }38 w += nw;39 }40 lookup[key] = {cnt, w};41 }42 return lookup[key];43 };44 45 return dp(0, -1, -1, true, true).second;46 };47 48 return count(num2) - count(num1 - 1);49 }50};51 52535455class Solution2 {56public:57 long long totalWaviness(long long num1, long long num2) {58 const auto& count = [&](long long x) {59 auto encode = [&](int prev, int prev2, int zero, int tight) {60 long long key = prev + 1;61 key = key * (10 + 1) + (prev2 + 1);62 key = key * 2 + zero;63 key = key * 2 + tight;64 return key;65 };66 67 const auto& s = to_string(x);68 const int state_size = (10 + 1) * (10 + 1) * 2 * 2;69 vector<pair<long long, long long>> dp(state_size, {-1, -1});70 vector<pair<long long, long long>> new_dp(state_size, {-1, -1});71 for (int prev = -1; prev <= 9; ++prev) {72 for (int prev2 = -1; prev2 <= 9; ++prev2) {73 for (int zero = 0; zero <= 1; ++zero) {74 for (int tight = 0; tight <= 1; ++tight) {75 const auto& key = encode(prev, prev2, zero, tight);76 dp[key] = {1, 0};77 }78 }79 }80 }81 for (int i = size(s) - 1; i >= 0; --i) {82 fill(begin(new_dp), end(new_dp), make_pair(-1LL, -1LL));83 for (int prev = -1; prev <= 9; ++prev) {84 for (int prev2 = -1; prev2 <= 9; ++prev2) {85 for (int zero = 0; zero <= 1; ++zero) {86 for (int tight = 0; tight <= 1; ++tight) {87 long long cnt = 0, w = 0;88 const auto& mx = tight ? s[i] - '0' : 9;89 for (int d = 0; d <= mx; ++d) {90 const auto& new_tight = tight && (d == s[i] - '0');91 const auto& new_zero = zero && (d == 0);92 const auto& new_prev2 = prev;93 const auto& new_prev = !new_zero ? d : -1;94 const auto& key = encode(new_prev, new_prev2, new_zero, new_tight);95 if (dp[key].first != -1) {96 const auto& [new_cnt, nw] = dp[key];97 cnt += new_cnt;98 if (!zero && prev2 != -1 && ((prev2 < prev && prev > d) || (prev2 > prev && prev < d))) {99 w += new_cnt;100 }101 w += nw;102 }103 }104 const auto& key = encode(prev, prev2, zero, tight);105 new_dp[key] = {cnt, w};106 }107 }108 }109 }110 swap(dp, new_dp);111 }112 113 return dp[encode(-1, -1, true, true)].second;114 };115 116 return count(num2) - count(num1 - 1);117 }118};119 120121122123class Solution3 {124private:125 struct TupleHash {126 template <typename... T>127 std::size_t operator()(const std::tuple<T...>& t) const {128 return apply([](const auto&... args) {129 std::size_t seed = 0;130 ((seed ^= std::hash<std::decay_t<decltype(args)>>{}(args) +131 0x9e3779b9 + (seed << 6) + (seed >> 2)), ...);132 return seed;133 }, t);134 }135 };136 137public:138 long long totalWaviness(long long num1, long long num2) {139 auto count = [&](long long x) {140 const auto& s = to_string(x);141 using State = tuple<int, int, int, bool, bool>;142 unordered_map<State, pair<long long, long long>, TupleHash> lookup;143 const auto dp = [&](this auto&& dp, int i, int prev, int prev2, bool zero, bool tight) -> pair<long long, long long> {144 if (i == size(s)) {145 return {1, 0};146 }147 State key = {i, prev, prev2, zero, tight};148 if (!lookup.count(key)) {149 long long cnt = 0, w = 0;150 const auto& mx = tight ? (s[i] - '0') : 9;151 for (int d = 0; d <= mx; ++d) {152 const auto& new_tight = tight && (d == mx);153 const auto& new_zero = zero && (d == 0);154 const auto& new_prev2 = prev;155 const auto& new_prev = !new_zero ? d : -1;156 const auto& [new_cnt, nw] = dp(i + 1, new_prev, new_prev2, new_zero, new_tight);157 cnt += new_cnt;158 if (!zero && prev2 != -1 && ((prev2 < prev && prev > d) || (prev2 > prev && prev < d))) {159 w += new_cnt;160 }161 w += nw;162 }163 lookup[key] = {cnt, w};164 }165 return lookup[key];166 };167 168 return dp(0, -1, -1, true, true).second;169 };170 171 return count(num2) - count(num1 - 1);172 }173};174 175176177178class Solution4 {179private:180 struct TupleHash {181 template <typename... T>182 std::size_t operator()(const std::tuple<T...>& t) const {183 return apply([](const auto&... args) {184 std::size_t seed = 0;185 ((seed ^= std::hash<std::decay_t<decltype(args)>>{}(args) +186 0x9e3779b9 + (seed << 6) + (seed >> 2)), ...);187 return seed;188 }, t);189 }190 };191 192public:193 long long totalWaviness(long long num1, long long num2) {194 const auto& count = [&](long long x) {195 const auto& s = to_string(x);196 using State = tuple<int, int, int, int>;197 unordered_map<State, pair<long long, long long>, TupleHash> dp, new_dp;198 for (int prev = -1; prev <= 9; ++prev) {199 for (int prev2 = -1; prev2 <= 9; ++prev2) {200 for (int zero = 0; zero <= 1; ++zero) {201 for (int tight = 0; tight <= 1; ++tight) {202 dp[{prev, prev2, zero, tight}] = {1, 0};203 }204 }205 }206 }207 for (int i = size(s) - 1; i >= 0; --i) {208 new_dp.clear();209 for (int prev = -1; prev <= 9; ++prev) {210 for (int prev2 = -1; prev2 <= 9; ++prev2) {211 for (int zero = 0; zero <= 1; ++zero) {212 for (int tight = 0; tight <= 1; ++tight) {213 long long cnt = 0, w = 0;214 const auto& mx = tight ? s[i] - '0' : 9;215 for (int d = 0; d <= mx; ++d) {216 const auto& new_tight = tight && (d == s[i] - '0');217 const auto& new_zero = zero && (d == 0);218 const auto& new_prev2 = prev;219 const auto& new_prev = !new_zero ? d : -1;220 State key = {new_prev, new_prev2, new_zero, new_tight};221 if (dp.count(key)) {222 const auto& [new_cnt, nw] = dp[key];223 cnt += new_cnt;224 if (!zero && prev2 != -1 && ((prev2 < prev && prev > d) || (prev2 > prev && prev < d))) {225 w += new_cnt;226 }227 w += nw;228 }229 }230 new_dp[{prev, prev2, zero, tight}] = {cnt, w};231 }232 }233 }234 }235 swap(dp, new_dp);236 }237 238 return dp[{-1, -1, true, true}].second;239 };240 241 return count(num2) - count(num1 - 1);242 }243};244