数位dp板子(待补充)

zzzsacmblog / 2024-03-08 / 原文

#include<iostream>
#include<vector>
#include<algorithm>
#include<math.h>
#include<string>
#include<string.h>
#include<iomanip>
#include<map>
#include<queue>
using namespace std;
typedef long long ll;

const int N = 15;
ll dp[N][N];
int num[N], now;
ll dfs(int pos, int sum, bool lead, bool limit)//pos:第pos位
{
	ll ans = 0;
	if (pos == 0)return sum;//0位数
	if (!lead and !limit and dp[pos][sum] != -1)return dp[pos][sum];//如果已经记忆了,那就直接返回
	int up = (limit ? num[pos] : 9);//limit:数位限制
	for (int i = 0; i <= up; i++)
	{
		if (i == 0 and lead)ans += dfs(pos - 1, sum, true, limit and i == up);
		//pos-1:处理下一位,
		else if (i == now)ans += dfs(pos - 1, sum + 1, false, limit and i == up);
		else if (i != now)ans += dfs(pos - 1, sum, false, limit and i == up);
	}
	if (!lead and !limit)dp[pos][sum] = ans;
	return ans;

}
ll solve(ll x)
{
    int len = 0;
	while (x)
	{
		num[++len] = x % 10;
		x /= 10;
	}
	memset(dp, -1, sizeof(dp));
	return dfs(len, 0, true, true);
}
int main()
{
	ll a;
	cin >> a;
	for (int i = 0; i < 10; i++)now = i, cout << solve(a)<<' ';
	return 0;
}