La fuga de los vigilantes del grupo popular noip de 2007

[Tema Descripción]

El cazador de demonios You Chian es ambicioso. Traicionó a los elfos de la noche y dirigió a Naga, que se escondía en el fondo del mar, en un intento de rebelarse: el vigilante se encontró con un asedio en el enfrentamiento con Yudian y quedó atrapado en una gran isla desierta. Para matar al vigilante, Yudian comenzó a maldecir la isla desierta, que pronto se hundirá. Para entonces, todos los que están en el cuchillo habrán muerto: la velocidad de carrera del vigilante es de 17 m / s, Es imposible escapar de la isla desierta a esta velocidad. Afortunadamente, el vigilante tiene el hechizo de parpadeo, que puede moverse 60 m en 1 s, pero cada vez que se usa el hechizo de parpadeo, consume 10 maná. La velocidad de recuperación de maná del vigilante es de 4 puntos / s, y solo se puede recuperar cuando descansa en el lugar.

Ahora se sabe que el valor inicial de la magia del vigilante es M, la distancia S entre su posición inicial y la salida de la isla, y el tiempo T cuando la isla se hunde. Tu tarea es escribir un programa para ayudar al vigilante a calcular cómo escapar de la isla desierta en el menor tiempo posible. Si no puede escapar, muestra la distancia más lejana que el vigilante puede caminar en el tiempo restante. Nota: Las actividades de correr, parpadear o descansar del vigilante se miden en segundos. Y la duración de cada actividad es un número entero de segundos. La unidad de distancia es metro (m).

Entrada El
archivo de entrada escape.in es solo una línea, incluyendo tres enteros no negativos M, S, T separados por espacios.

Salida El
archivo de salida escape.out contiene dos líneas:

La primera línea es la cadena "Sí" o "No" (distingue entre mayúsculas y minúsculas), es decir, si el vigilante puede escapar de la isla desierta.

La segunda línea contiene un número entero, la primera línea "Sí" (distingue entre mayúsculas y minúsculas) significa el tiempo más corto para escapar de la isla desierta.

Cuando la primera línea es "No" (distingue entre mayúsculas y minúsculas), significa la distancia más larga que puede recorrer el observador.

Entrada de muestra 39200
4
Salida de muestra
No
197
indica que el
30% de los datos cumple: 1 <= T <= 10, 1 <= S <= 100 El
50% de los datos cumple: 1 <= T <= 1000, 1 <= S <= 10000 El
100% de los datos satisface: 1 <= T <= 300000, 0 <= M <= 1000 1 <= S <= 10 ^ 8

【análisis】

1. Buscar

La búsqueda memorizada está bien, pero en principio, si el límite de memoria no es lo suficientemente grande, 30w dfs romperá la pila, aquí no debe usarse dfs sino bfs ...
Primero busque todo f [i] [j] f [i] [j ]F [ i ] [ j ] resulta,F [i] [j] denota el i-ésimo segundo, la cantidad de azul restante j es la distancia máxima que se puede recorrer F [i] [j] denota el i-ésimo segundo, la cantidad restante de azul j La distancia mas largaf [ i ] [ j ] de la tabla muestra los primeros i segundos , restantes más de azul cantidad se j pueden tomar la más lejos de distancia desde la última f atravesar toda la matriz para encontrar una solución óptima a

#include<bits/stdc++.h>
using namespace std;
int m,s,t,ans,anstime;
int f[300105][15]={0};
void dfs(int nowtime,int way,int value){
	if (nowtime > t) return;        //若超出规定时间t则结束搜索
	if (f[nowtime][value] >= way) return;  //对当前状态判断是否比之前记录过的状态更优,若更优才继续搜索
	f[nowtime][value] = way;
	if (way >= s) return;     // 若当前移动的距离已经超过目标距离了,那么之后的搜索都是无意义的
	if (value >= 10){    //若当前蓝量足够闪烁,那么显然立刻闪烁是最优解
		dfs(nowtime+1,way+60,value-10);
	}
	else{
		//搜索移动和停止在原地回蓝两种状态
		dfs(nowtime+1,way,value+4);
		dfs(nowtime+1,way+17,value);
	}
}

int main() 
{
	memset(f,-1,sizeof(f));
	scanf("%d%d%d",&m,&s,&t);
 	int starttime = 0,start = 0;
	while (m >= 10 && starttime < t && start < s){
		//毋庸置疑,一开始将初始有的蓝全部用完
		m-=10;
		start+=60;
		++starttime;
	}
	//两个特殊情况,即蓝没用完,却已经逃离了,或蓝没用完,时间到了
	if (start >= s){
		printf("Yes\n%d",starttime);
		return 0;
	}
	if (starttime == t){
		printf("No\n%d",start);
		return 0;
	}
	dfs(starttime,start,m);
	int ans = 0;
	//在所有的状态中搜索一个最优解,若某次搜索发现已经逃离,那么当前时间就是最小时间
	for(int i = 1 ; i <= t ; ++i)
		for (int j = 0; j <= 14 ; ++j)
		{
			ans = max(ans,f[i][j]);
			if (f[i][j] >= s){
				printf("Yes\n%d",i);
				return 0;
			}
		} 	
 	printf("No\n%d",ans);
 	return 0;
}

2.dp

Use F [t] para representar la distancia más lejana que el observador puede viajar en t tiempo, y G [t] representa la distancia más lejana que el observador puede caminar en t tiempo usando solo el hechizo parpadeante. Entonces la ecuación de transición de estado correspondiente es
{F [0] = G [0] = 0 F [t] = max (F [t - 1] + 17, G [t]) \ begin {cases} F [0] = G [0] = 0 \\ F [t] = max (F [t-1] + 17, G [t]) \ end {cases}{ F [ 0 ]=G [ 0 ]=0F [ t ]=m a x ( F [ t-1 ]+1 7 ,G [ t ] )

#include <stdio.h>

int main() {
    int m, s, t;
    int i, d1, d2; 
    scanf("%d%d%d", &m, &s, &t);
    d1 = d2 = 0;
    for (i = 1; i <= t; i++) {
        if (m >= 10) {
            d1 += 60; m-= 10;
        } else {
            m += 4;
        }
        if (d1 > d2 + 17) d2 = d1;
        else d2 += 17;
        if (d2 >= s) break;
    }
    if (i > t) printf("No\n%d\n", d2);
    else printf("Yes\n%d\n", i);
    return 0;
}

Supongo que te gusta

Origin blog.csdn.net/jnxxhzz/article/details/86669979
Recomendado
Clasificación