# 4780. Investigación de virus

Descripción del título

La científica de virus Dra. Chen está liderando a su equipo para estudiar el virus y quiere estudiar cómo reducir la actividad del virus. La actividad del virus puede estar representada por un número entero, pero ella no conoce la actividad específica.

Puede realizar operaciones de $ m + 1 $. Para las primeras operaciones de $ m $, la primera operación de $ i $ es el costo de gastar $ v_i $ y la actividad del virus se reduce en $ w_i $; la operación de $ m + 1 $ es Verifique el estado actual del virus sin costo.

Hay un total de $ n $ estados para virus. Hay $ n + 1 $ números incrementales $ a_0, a_1, a_2, ..., a_n $, donde $ a_0 = 0 $; si la actividad del virus $ x $ satisface $ a_ {i-1} <x \ le a_i $, entonces el virus está en el estado $ i $. Al mismo tiempo, asegúrese de que la actividad del virus no sea superior a $ a_n $.

Puede usar cada operación tantas veces como quiera, pero no quiere que el virus esté completamente inactivo. Pero si después de usar una operación, la actividad del virus $ \ le 0 $, entonces el estudio falla. Y la actividad del virus es demasiado alta para la investigación, solo cuando el virus está en el estado $ 1 $ es el más adecuado para la investigación.

Ahora, ella solo sabe que la actividad del virus es un entero aleatorio de igual probabilidad en $ [1, a_n] $. Quiere saber lo que espera gastar menos en el proceso de hacer que el virus $ 1 $ mientras se asegura de que el virus no pierda su actividad por completo.

Se puede encontrar que la respuesta multiplicada por $ a_n $ debe ser un número entero, la respuesta de salida multiplicada por el valor de $ a_n $.

Si no hay garantía de que el virus no perderá actividad por completo, genere $ -1 $.

Rango de datos

$ 1 \ le a_1 <a_2 <... <a_n \ le 2000, 1 \ le T \ le 10, 1 \ le v_i \ le 10 ^ 6 $。

Solución

Considere $ \ text {dp} $: $ f [l] [r] $ significa que el número en $ [l, r] $ alcanza la suma esperada de $ 1 $. Considere $ l, r $ si no está en un estado, es una suma de varios $ \ text {dp} $, si está en un estado, se traducirá hacia adelante y agregará el costo de la traducción hacia adelante, esto es $ O (n ^ 2m) $.

Considerando la posibilidad de reducir el número de estados, podemos suponer que se ha traducido a la posición de la primera división, luego este proceso se puede implementar con una mochila. Entonces solo necesitamos recordar los estados de $ f [a_ {i-1} +1] [x] $ y $ f [x] [a_i] $, donde $ x $ está en el estado $ i $. Esta eficiencia es $ O (nm) $.

Código

 

#include <bits / stdc ++. h>
 #define LL largo largo
 usando el  espacio de nombres std;
const  int N = 2005 ;
const LL G = 1e18;
int T, n, m, z, a [N], b [N]; 
LL f [N] [N], g [N], s [N]; 
LL F ( int l, int r) {
     if (f [l] [r]! = G) return f [l] [r];
    para ( int x, y, i = 1 ; i <l; i ++ )
         if (g [i]! = G && (b [li]! = b [ri] || ri <= a [ 1 ])) { 
            x = li; y = r- i; 
            LL u= g [i] * (r-l + 1 ) + F (x, a [b [x]]) + F (a [b [y] - 1 ] + 1 , y);
            if (b [x] + 1 <b [y]) u + = s [b [y] - 1 ] - s [b [x]]; 
            f [l] [r] = min (u, f [l] [r]); 
        } 
    return f [l] [r]; 
} 
trabajo nulo () { 
    scanf ( " % d% d " , & n, & m); 
    memset (b, 0 , tamaño de b);
    para ( int i = 1 ; i <= n; i ++ ) 
        scanf ( " % d ", & a [i]), 
        b [a [i] + 1 ] ++; z = a [n]; b [ 0 ] = 1 ;
    para ( int i = 1 ; i <= z; i ++ ) 
        b [i] + = b [i- 1 ], g [i] = G;
    para ( int x, y; m-- ;) { 
        scanf ( " % d% d " , & x, & y);
        para ( int i = y; i <= z; i ++ ) 
            g [i] = min (g [i], g [iy] + x); 
    } 
    para ( int i = 1; i <= z; i ++ )
         para ( int j = i; j <= z; j ++) f [i] [j] = G;
    para ( int i = 1 ; i <= a [ 1 ]; i ++ )
         para ( int j = i; j <= a [ 1 ]; j ++) f [i] [j] = 0 ;
    para ( int x, y, i = 2 ; i <= n; i ++ ) { 
        x = a [i- 1 ] + 1 ; y = a [i];
        para ( int r = x; r <= y; r ++) f [x] [r] = F (x, r);
        para ( intl = x; l <y; l ++) f [l] [y] = F (l, y);
        if (f [x] [y] == G) {pone ( " -1 " ); return ;} 
        s [i] = s [i- 1 ] + f [x] [y]; 
    } 
    printf ( " % lld \ n " , s [n]); 
} 
int main () { for (cin >> T; T -; work ()); devuelve  0 ;}

 

Supongo que te gusta

Origin www.cnblogs.com/xjqxjq/p/12727407.html
Recomendado
Clasificación