algoritmo de DP - POJ 4121: el comercio de acciones

título Descripción

límite de tiempo total: 1000ms Límite de memoria: 65536kB
descrito
recientemente que más y más gente se une a la bolsa de valores, Fu también un poco de corazón. Recuerde que el "riesgo de mercado de valores, los inversores deben tener cuidado," Fu decidió buscar a una versión simplificada de la emisión de acciones de comercio.

Fu ha supuesto que predijo con exactitud el precio de una acción en los próximos N días, que espera que la venta de los dos, por lo que los mayores beneficios obtenidos. Para el cálculo de la simplicidad, el beneficio se calcula como el precio de venta menos el precio de compra.

El mismo día se pueden negociar varias veces. Pero después de la primera compra, usted debe vender antes de que puedan comprar una segunda vez.

Ahora, Fu quería saber la cantidad de beneficios que puede obtener hasta.

De entrada
de la primera línea de la entrada es un número entero T (T <= 50), T representa un conjunto total de datos.
A continuación, cada grupo de datos, la primera línea es un número entero N (1 <= N <= 100, 000), N denota un día total. La segunda línea es la N separados por espacios entero que indica el precio de las acciones cada día. El valor absoluto del precio de la acción diaria no excederá de 1.000.000.
Output
Para cada línea de salida de datos. La línea contiene un entero que representa el máximo beneficio que puede obtenerse Fu.
entrada de la muestra
. 3
. 7
. 5 14. 4. 9. 3. 17 -2
. 6
. 6. 8. 7. 4 1 -2
. 4
18 es 2. 5. 9
salida de muestra
28
2
0
símbolo
para el primer conjunto de la muestra, puede primero Fu Día 1 compra (precio es 5), a continuación, venta (precio de 14) en el día 2. 2º Día 3 compra (precio -2), y luego vender (precio de 17) en el día 7. se obtiene el beneficio total (14 a -5) + (17 - (-2)) = 28
para el segundo conjunto de muestra, puede Fu primera Día 1 Compra (precio 6), entonces el segundo días de venta (precio es 8). El segundo se encuentra todavía en los primeros dos días para comprar, vender y luego al día siguiente. Un total de beneficios obtenidos es 8--6 = 2
para el tercer juego de la muestra, ya que los precios han estado cayendo, Fu podría optar por vender rápidamente después de días de compra. Se obtiene el máximo beneficio 0

Ideas de resolución de problemas

Otra cuestión que se plantea aquí, aunque sólo sea para permitir la venta de uno, el beneficio máximo disponible para contar cómo?
Conjunto dp [i] representa los primeros días de negociación antes de que consiga el máximo beneficio.
Estado inicial: dp [0] = 0, el número de días contados a partir de 0, es decir, en el día 0 inmediatamente después de la venta para comprar.
de transición de estados: dp [i] = max { dp [i-1], st [i] - min}, min es el día de valores más bajos antes de i
problema resuelto utilizando programación dinámica.

A continuación, la pregunta del título, requiere el doble de la venta, si las ideas anteriores para llevar solución similar, se necesitan dos matrices dp, la representación DP1 antes de día i (incluyendo el día i) una vez que la venta de las mayores ganancias, la representación DP2 aumentos máximos tras día (incluyendo el i-ésimo día), después max {DP1 [i] DP2 [i] +}, está la solución de la solución problema.

código

#include <cstdio>
#include <cstring>
#include <algorithm>

int st[100010];
int dp1[100010]; //dp1表示前i天最大收益
int dp2[100010]; //dp2表示后i天最大收益

int main(){
    int t;
    scanf("%d", &t);
    while(t--){
        memset(st, 0, sizeof(st));
        memset(dp1, 0, sizeof(dp1));
        memset(dp2, 0, sizeof(dp2));
        int n;
        scanf("%d", & n);
        for(int i = 0; i < n; i++){
            scanf("%d", &st[i]);
        }
        
        int minn = st[0];
        int maxn = st[n-1];
        for(int i = 1; i < n; i++){
            if(st[i] < minn)
                minn = st[i];
            dp1[i] = std:: max(dp1[i-1], st[i] - minn);
        }
        for( int i = n - 2; i>=0 ; i--){
            if(st[i] > maxn)
                maxn = st[i];
            dp2[i] = std:: max(dp2[i+1], maxn - st[i]);
        }
        
        int max = 0;
        for(int i = 0; i < n; i++){
            if(dp1[i] + dp2[i] > max)
                max = dp1[i] + dp2[i];
        }
        printf("%d\n", max);
        
    }
    return 0;
}

Supongo que te gusta

Origin www.cnblogs.com/zhangyue123/p/12565028.html
Recomendado
Clasificación