CodeForces-914C Digital DP

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;
}
/*




 * */

Supongo que te gusta

Origin blog.csdn.net/Tighway/article/details/98227700
Recomendado
Clasificación