#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;
}
标签:int,ll,pos,板子,limit,include,dp,数位
From: https://www.cnblogs.com/zzzsacmblog/p/18059899