Tabla de contenido
Copa Lanqiao 2023 14° Concurso Provincial Preguntas Reales-Maigua
Copa Lanqiao 2023 14° Concurso Provincial Preguntas Reales-Maigua
Límite de tiempo: 3 s Límite de memoria: 320 MB Envía: 796 Resuelve: 69
Descripción de la pregunta
Xiao Lan está comprando melones en un puesto de melones. Hay n melones en el puesto de melones y el peso de cada melón es Ai.
Little Blue Knife es tan bueno que puede dividir cualquier melón en dos partes de exactamente el mismo peso, pero solo puede cortar cada melón una vez.
Xiaolan espera que la suma de los pesos de los melones que quiere comprar sea exactamente m.
Pregúntele a Xiao Lan al menos cuántos melones tiene que partir para comprar un melón con un peso exacto de m. Si Xiaolan no puede obtener un melón con un peso total de exactamente m pase lo que pase, genere −1.
Formato de entrada
La primera línea de entrada contiene dos números enteros n y m, separados por un espacio, que representan respectivamente la cantidad de melones y el peso total de los melones que Xiaolan quiere comprar.
La segunda línea contiene n enteros Ai, separados por un espacio entre enteros adyacentes, que representan el peso de cada melón respectivamente.
Formato de salida
Una línea de salida contiene un número entero que representa la respuesta.
Entrada de muestra
Copiar
3 10 1 3 13
Salida de muestra
Copiar
2
pista
Para el 20% de los casos de uso de evaluación, ∑n≤10;
Para el 60% de los casos de evaluación, ∑n≤20;
Para todos los casos de evaluación, 1 ≤ n ≤ 30, 1 ≤ Ai ≤ 109, 1 ≤ m ≤ 10^9
[Análisis de ideas]
Esta pregunta es una lista muy simple de posibilidades recursivas, pero hay tres situaciones en cada recursión, por lo que la complejidad del tiempo es O (3 ^ N). La complejidad del tiempo es demasiado alta, por lo que es necesario deshacerse de esas recursiones completas. Durante el proceso de recursividad, las soluciones imposibles reducen la complejidad.
【Código】
package LQB;
import java.util.Scanner;
/**
* @ProjectName: study3
* @FileName: Ex4
* @author:HWJ
* @Data: 2023/9/17 21:54
*/
public class Ex4 {
static double[] subs; // subs[i]表示为西瓜i -西瓜n-1的西瓜质量和,用于对递归的降低可能性
static double m;
static int n;
static int min = 40; // 因为n最大为30,所以最多劈瓜30次
static double[] weights; // weights[i]表示为第i个西瓜的质量
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
n = input.nextInt();
m = input.nextInt();
weights = new double[n];
subs = new double[n];
for (int i = 0; i < n; i++) {
weights[i] = input.nextInt();
}
subs[n - 1] = weights[n - 1];
for (int i = n - 2; i >= 0; i--) {
subs[i] = subs[i + 1] + weights[i];
}
int p = dfs(0, 0, 0);
System.out.println(p == Integer.MAX_VALUE ? -1 : p);
}
// sum 表示现在搞定了多少西瓜 index 表示现在对第几个西瓜做决策 have表示现在已经劈了几次瓜了
public static int dfs(double sum, int index, int have) {
if (have >= min) { // 如果此时虽然满足要求但他大于了当前的最优情况,他不可能是最优解,直接排除掉
return Integer.MAX_VALUE;
}
if (sum == m) { // 达到满足要求
min = have; // 更新最小情况。
return have;
}
if (sum > m) {
return Integer.MAX_VALUE; // 此时不加任何西瓜 重量也已经超过了需要的重量,所以直接排除
}
if (index == n) {
return Integer.MAX_VALUE; //此时已经使用了所有西瓜,也无法满足,直接排除掉
}
if (subs[index] + sum < m) {
return Integer.MAX_VALUE; // 此时加上后面所有的西瓜也不满足条件,所以没有必要再递归了,
}
int p1 = dfs(sum + weights[index], index + 1, have);
int p2 = dfs(sum + weights[index] / 2.0, index + 1, have + 1);
int p3 = dfs(sum, index + 1, have);
return Math.min(p1, Math.min(p2, p3));
}
}