ABC 154
Table of Contents
https://atcoder.jp/contests/abc154
A. Remaining Balls
https://atcoder.jp/contests/abc154/tasks/abc154_a
B. I miss you
https://atcoder.jp/contests/abc154/tasks/abc154_b
C. Distinct or Not
https://atcoder.jp/contests/abc154/tasks/abc154_c
D. Dice in Line
https://atcoder.jp/contests/abc154/tasks/abc154_d
E. Almost Everywhere Zero
https://atcoder.jp/contests/abc154/tasks/abc154_e
自力 AC. 桁 DP の問題だということをわかった上で解いた。
dp[i][is_less][c]
を上位 $i$ 桁目まで見ていて、$N$ よりも小さいことが確定しているフラグ is_less
と、0 以外の数字の個数 c
を持つ DP 配列を定義する。
dp 配列を更新する際、$0$ 以外の数が $K+1$ となるケースは興味ないので全て $K+1$ に丸めておく。
void solve() {
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
string N;
ll K;
cin >> N >> K;
int M = N.size();
vector dp(M + 1, vector(2, vll(K + 2)));
dp[0][0][0] = 1;
rep2(i, 1, M + 1) {
int t = N[i - 1] - '0';
rep(d, 10) {
int is_not_zero = d != 0;
rep(c, 4) {
int nxc = min(c + is_not_zero, K + 1);
if (d < t) {
dp[i][1][nxc] += dp[i - 1][0][c];
}
if (d == t) {
dp[i][0][nxc] += dp[i - 1][0][c];
}
dp[i][1][nxc] += dp[i - 1][1][c];
}
}
}
ll ans = dp[M][1][K] + dp[M][0][K];
cout << ans << endl;
}