División de polígono convexo "Intervalo DP-Step"

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 50norte50 , el peso de cada punto es menor que1 0 9 10^91 09 _
  • https://ac.nowcoder.com/acm/problem/50500

analizar

1643528400834

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]);
    }
}

Supongo que te gusta

Origin blog.csdn.net/qq_43098197/article/details/130318282
Recomendado
Clasificación