CodeForces-914C Digital DP
La pregunta intenta dar un número binario n y un entero k, cuántos números de 1-n a 1 son k.
El paso aquí significa que el número actual se convierte en el número de bits binarios 1. Por ejemplo, 5-> 2-> 1, dos pasos.
n puede ser muy grande, pero la longitud del paso no excederá 1000. El número preprocesado es de 1 a 1. ¿Cuál es la longitud del paso de 1 a 1? Los primeros 1000 son suficientes.
Pero dp me hace sentir un poco difícil de pensar. Enumere de mayor a menor. Cuando el i-ésimo bit es 1, corrija el bit más alto que i. Suponiendo que el i-ésimo bit es 0, entonces puede enumerar todos los bits binarios del bit. Sucediendo. (Debido a que el i-ésimo bit se establece en 0, se garantiza que no excederá i)
La enumeración se puede optimizar por el número de combinaciones, enumere el número de 1 y, si se satisface el número actual, agregue el número de combinaciones a la respuesta.
Finalmente, si no procesa la posición actual 1 en el ciclo, agréguela al final.
Tenemos que juzgar el caso especial de 0 y el caso especial de 1. (El tamaño de paso de 1 a 1 es 0, pero el binario solo tiene otro número y el tamaño de paso a 1 es 1)
Hay una plantilla para el número de combinaciones ==, que puede no ser bonita. Si no te gusta, puedes escribir una tú mismo.
#define _debug(x) cerr<<#x<<" = "<<x<<endl
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 1e3 + 59;
const int MOD = 1e9 + 7;
template<typename _Tp, const int BCSize, const _Tp Mod> //add Mod as parameter;
struct Binomial_Coefficient {
_Tp fac[BCSize + 1];
_Tp inv[BCSize + 1];
inline Binomial_Coefficient() {
//add Mod as parameter;
fac[0] = 1;
for (int i = 1; i <= BCSize; i++)
fac[i] = fac[i - 1] * i % Mod;
inv[BCSize] = 52180388;
// printf inv[BCSize] to get & save it;
for (int i = BCSize - 1; ~i; i--)
inv[i] = inv[i + 1] * (i + 1) % Mod;
}
inline _Tp operator()(const int &n, const int &m) {
return fac[n] * inv[m] % Mod * inv[n - m] % Mod;
}
};
typedef Binomial_Coefficient<long long, 1000, MOD> zuHeShu;
zuHeShu C = zuHeShu();
int kase, Kase;
char s[MAXN];
ll step[MAXN], bits[MAXN], k;
ll dp[MAXN];
int len;
int main() {
ios_base::sync_with_stdio(0);
cin.tie(0);
cin >> (s + 1) >> k;
if (k == 0) {
cout << 1 << endl;
return 0;
}
for (int i = 1; i <= 1000; i++) {
bits[i] = bits[i >> 1] + (i & 1);
step[i] = step[bits[i]] + 1;
}
step[1] = 1;
step[0] = MAXN;
len = strlen(s + 1);
int cnt1 = 0;
for (int i = 1; i <= len; ++i) {
dp[i] = dp[i - 1];
if (s[i] == '1') {
for (int j = 0; j <= len - i; ++j)
if (step[cnt1 + j] == k)
dp[i] = (dp[i] + C(len - i, j)) % MOD;
cnt1++;
}
}
if (step[cnt1] == k)
dp[len] = (dp[len] + 1) % MOD;
if (k == 1)
dp[len] = (dp[len] + MOD - 1) % MOD;
cout << dp[len] << endl;
return 0;
}
/*
* */