Digit Products

char s[501];
int k, n, m, a[501];
//https://atcoder.jp/contests/abc208/tasks/abc208_e
//求n以内的数满足每个十进制位相乘后小于k的个数
//学到了因为乘积的个数不多,所以不能用数组但是可以用map存储dp
map<pair<pair<int, ll>, pair<bool, bool>>, ll> dp;
ll solve(int pos, ll now, bool limit, bool zero) {
    if(pos == n)    return now <= k;
    pair<pair<int, ll>, pair<bool, bool>> tmp = {{pos, now}, {limit, zero}};
    if(!limit & dp.count(tmp))   return dp[tmp];
    int up = limit ? a[pos] : 9;
    ll ans = 0;
    for(int i = 0; i <= up; ++ i) {
        int mul = i; if(mul == 0 && zero)   mul = 1;
        ans += solve(pos + 1, now * mul, limit & (i == up), zero & (i == 0));
    }
    return limit ? ans : dp[tmp] = ans;
}

signed main() {
    scanf("%s %d", s, &k);
	n = (int )strlen(s);
	for (int i = 0; i < n; i ++)
		a[i] = s[i] - '0';
	printf("%lld\n", solve(0, 1, 1, 1) - 1);
    return 0;
}

posted @ 2022-03-05 11:59  wansheking  阅读(34)  评论(0)    收藏  举报