[Informe de resolución de problemas] Resultado de la simulación del Grupo B de la Copa Blue Bridge 2020 de un pasajero con ajo que llena los espacios en blanco: Apple

Descripción del problema

Hay 3030 canastas y cada canasta contiene varias manzanas Se ha dado la secuencia del número de manzanas en la canasta.

Ahora tenemos que distribuir las manzanas a los niños. Cada niño tomará tres manzanas de una canasta o una manzana de cada una de las tres canastas adyacentes.

Apple puede permanecer, y diferentes formas de agarrar llevarán a diferentes respuestas. Por ejemplo, para la secuencia 3 1 3, se puede asignar a dos niños para que se convierta en 0 1 0; también se puede asignar a un niño para que se convierta en 2 0 2. En este momento, ya no se puede dividir. Entonces la respuesta es 22.

Para la siguiente secuencia, ¿cuántos hijos se pueden compartir como máximo?


Siempre que desee lo máximo o lo mínimo, el 95% son ideas de búsqueda amplia o búsqueda profunda

Hay muchos blogs en Internet que usan soluciones codiciosas, lo cual no es correcto en absoluto. Esta pregunta es codiciosa y solo puede dar ejemplos. Está mal cambiar los datos con puntos engañosos.

La idea correcta es DFS. Solo hay dos operaciones para tomar el número, ya sea un solo -3 o tres adyacentes -1. Luego, siempre que use la simulación de búsqueda profunda y recorra cada posibilidad, naturalmente puede encontrar el mínimo.


Nota: Si simplemente usa la búsqueda para ejecutar, entonces cada número debe tomar los dos adyacentes cada menos uno y tomar el número menos tres operaciones, es decir, debe ejecutar 3 a la 30 potencia, para la computadora Todavía es muy lento, por lo que debe optimizarse con la poda.


Código de referencia

#include<bits/stdc++.h>
using namespace std;

int ans = 0; 
int a[117] = {
    
    7,2,12,5,9, 9,8,10,7,10, 5,4,5,8,4, 4,10,11,3,8, 7,8,3,2,1, 6,3,9,7,1};
int sum[117];

void dfs(int idex, int num) {
    
    
	if(idex == 30) {
    
    
		ans = max(ans, num);
		return;
	}
	if(sum[idex] / 3 + num < ans) return; 	//剪枝优化
	//不公用
	dfs(idex+1, num+a[idex]/3);
	//往后公用 
	if(idex+2 < 30) {
    
    
		int min_num = min(a[idex], a[idex + 1]);
		min_num = min(min_num, a[idex+2]);		//共用最多能分几个
		for(int k = 1; k <= min_num; k++) {
    
    
			for(int i = 0; i < 3; i++) a[idex+i] -= k;
			dfs(idex+1, num+a[idex]/3+k);
			for(int i = 0; i < 3; i++) a[idex+i] += k;
		} 
	} 
}

int main() {
    
    
    for(int i = 29; i >= 0; i--) sum[i] = sum[i + 1] + a[i];
    for(int i = 0; i < 30; i++) cout << sum[i] << ' ';
    dfs(0, 0);
    cout << ans << endl;
    return 0;
}


Se puede esperar el futuro

Inserte la descripción de la imagen aquí

Supongo que te gusta

Origin blog.csdn.net/weixin_43899069/article/details/109098805
Recomendado
Clasificación