Petrozavodsk Invierno-2018. Concurso U Jagiellonian E. Juego de adivinanzas 【Presión ternaria DP】

Significado de la pregunta: como UVA1252, hay n 01 cadenas de longitud k, y puede saber qué cadena es preguntando la estrategia óptima y adivinando como máximo varias veces;

Análisis: la pregunta k de UVA es 11, que resulta ser una búsqueda violenta, pero esta pregunta es 13, tienes que pensar en el estado de DP, pero cada uno de estos tiene tres estados, que se han establecido como 1, ya establecidos como 2, e indeciso, por lo que es la presión de estado DP bajo el sistema ternario, primero puede preprocesar el valor de cada dígito en todos los estados bajo el sistema ternario y 3 ^ i (p [i]); procesar el estado que aparece durante el proceso de lectura y registrarlo. El siguiente número es 1, y luego escanear todos los estados. Por ejemplo, el j-ésimo bit del estado i es 2, lo que significa que este bit es desconocido, entonces el número que satisface este estado es state (ip [j]) y (ip [j] * 2), Significa que se sabe que el j-ésimo bit es la suma de 1 o 0. Una vez completado el procesamiento, el estado se transferirá. se encuentra una posición desconocida del estado, se puede transferir desde la posición conocida como 1 o 0, y el resultado debe incrementarse en uno, porque el juicio Si este bit es 1 o 0 todavía necesita una operación, y la respuesta es cuando la actualización se transfiere al último estado;

#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
#define pb push_back
using namespace std;
typedef long long ll;
const int maxn=1600000;
const int mod=1e9+7;
char s[20];
int p[15],val[maxn][14];
int num[maxn],a[15],dp[maxn];
void init()
{
    p[0]=1;
    for(int i=1;i<14;i++) p[i]=3*p[i-1];
    for(int i=0;i<p[13];i++)
    {
        int x=i;
        for(int j=0;j<13;j++) val[i][j]=x%3,x/=3;
    }
}
void rua()
{
    int n,k;scanf("%d%d",&n,&k);
    for(int i=0;i<p[k];i++) num[i]=0;
    for(int i=1;i<=n;i++)
    {
        scanf("%s",s);int x=0;
        for(int j=0;j<k;j++) x=x*3+(s[j]-'0');
        num[x]++;
    }
    for(int i=0;i<k;i++) 
        for(int j=0;j<p[k];j++) 
            if(val[j][i]==2) num[j]+=(num[j-p[i]]+num[j-p[i]*2]);
    for(int i=0;i<p[k];i++)
    {
        if(num[i]<=1) {dp[i]=0;continue;}
        int tmp=INF;
        for(int j=0;j<k;j++) 
            if(val[i][j]==2) tmp=min(tmp,max(dp[i-p[j]],dp[i-p[j]*2]));
        dp[i]=tmp+1;
    }
    printf("%d\n",dp[p[k]-1]);
}
int main()
{
    init();
    int t;scanf("%d",&t);
    while(t--) rua();
    return 0;
}

 

Supongo que te gusta

Origin blog.csdn.net/qq_43813163/article/details/102507238
Recomendado
Clasificación