División de polígonos convexos
Tema Descripción
Dado un polígono convexo con N vértices, etiqueta los vértices de 1 a N, y el peso de cada vértice es un número entero positivo. Divida este polígono convexo en N-2 triángulos separados entre sí e intente encontrar al menos la suma de los productos de peso de los vértices de estos triángulos.
ingrese la descripción
Ingrese la primera fila del número de vértice N y la segunda fila de pesos del vértice 1 al vértice N en secuencia.
descripción de salida
Muestra solo una línea, que es el valor mínimo de la suma del producto de los pesos de los vértices de estos triángulos.
muestra
5
121 122 123 245 231
12214884
ilustrar
- Para el 100% de los datos, hay N ≤ 50 N \leq 50norte≤50 , el peso de cada punto es menor que1 0 9 10^91 09 _
- https://ac.nowcoder.com/acm/problem/50500
analizar
De acuerdo con la rutina anterior, el título requiere una explicación, y haremos suposiciones, asumiendo [ i , j ] [i,j][ yo ,j ] es el triángulo dividido más pequeño.
Tomar BE ( [ 2 , 5 ] [2,5][ 2 ,5 ] ) como ejemplo, tomando BE como lado fijo como línea auxiliar, se puede dibujar BD o EC, y el triángulo se puede dividir en EBD y BDC o BEC y CED respectivamente, y los puntos divididos D y C se llaman puntos límite K.
可得方程:
dp [ i ] [ j ] = min ( dp [ i ] [ j ] , dp [ i ] [ k ] + dp [ k ] [ j ] + A [ i ] ∗ A [ j ] ∗ A [ k ] ) dp[i][j] = min(dp[i][j], dp[i][k] + dp[k][j] + A[i] * A[j] * A[k ])re pag [ yo ] [ j ]=min ( d p [ i ] [ j ] ,re pag [ yo ] [ k ]+re pag [ k ] [ j ]+un [ yo ]∗un [ j ]∗A [ k ])
inicialización:
- dp[i][j] = INF dp[i][j] = INFre pag [ yo ] [ j ]=NF _
el código
El siguiente código solo puede obtener 40 puntos (fácil de entender el proceso de DP)
public class Main {
static final int INF = 1 << 30;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int[] A = new int[n+1];
long[][] dp = new long[n+1][n+1];
for(int i = 1; i <= n; i++) A[i] = sc.nextInt();
for(int len = 3; len <= n; len++) {
for(int i = 1; i + len - 1 <= n; i++) {
int j = i + len - 1;
dp[i][j] = INF;
for(int k = i + 1; k < j; k++) {
dp[i][j] = Math.min(dp[i][j], dp[i][k] + dp[k][j] + (A[i] * A[j] * A[k]));
}
}
}
System.out.println(dp[1][n]);
}
}
código de CA
public class Main {
static BigInteger INF = new BigInteger("1000000000000000000000000000");
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
BigInteger[] A = new BigInteger[n+1];
BigInteger[][] dp = new BigInteger[n+1][n+1];
for(int i = 1; i <= n; i++) Arrays.fill(dp[i], new BigInteger("0"));
for(int i = 1; i <= n; i++) A[i] = new BigInteger(sc.nextInt() + "");
for(int len = 3; len <= n; len++) {
// 枚举区间
for(int i = 1; i + len - 1 <= n; i++) {
// 枚举区间起点
int j = i + len - 1; // 计算区间终点
dp[i][j] = INF;
for(int k = i + 1; k < j; k++) {
// 枚举分界点
BigInteger a = dp[i][j];
BigInteger t = new BigInteger("0");
if(dp[i][k] != null) t = t.add(dp[i][k]);
if(dp[k][j] != null) t = t.add(dp[k][j]);
if(A[i] != null && A[j] != null && A[k] != null) t = t.add(A[i].multiply(A[j]).multiply(A[k]));
if(a.compareTo(t) >= 1) dp[i][j] = t;
}
}
}
System.out.println(dp[1][n]);
}
}