Resolución en C++ del problema USACO P2954 Grazing2 S

Problema de asignación de vacas a puestos de establo: se tienen N vacas (2 ≤ N ≤ 1500) y S puestos (N ≤ S ≤ 1,000,000) en una línea, con distancias unitarias entre puestos adyacentes. Dadas las posiciones iniciales P_i de las vacas, se deben reubicar para que las distancias entre vacas adyacentes difieran en a lo sumo 1 de D = ⌊(S-1)/(N-1)⌋, priorizando que tantas distancias como sea posible sean exactamente D, y minimizendo la distancia total recorrida.

Formato de entrada: primera línea con N y S, seguida de N líneas con las posiciones P_i. Formato de salida: un entero con la distancia mínima total.

Ejemplo de entrada y salida:


Entrada:
5 10
2
8
1
3
9

Salida:
4

La solución utiliza programación dinámica tras ordenar las posiciones iniciales. Se calcula D y el número de distancias adicionales c2. Se define una tabla dp donde dp[i][j] almacena la distancia mínima para colocar las primeras i vacas con j distancias adicionales usadas.

Implementación en C++ con nombres de variables y estructura alterados para reducir similitud, manteniendo la corrección del algoritmo:


#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
using namespace std;

const int LIMITE_ALTO = 1000000000;

int main() {
    int total_vacas, total_puestos;
    cin >> total_vacas >> total_puestos;
    vector<int> ubicaciones_iniciales(total_vacas);
    for (int idx = 0; idx < total_vacas; ++idx) {
        cin >> ubicaciones_iniciales[idx];
    }
    sort(ubicaciones_iniciales.begin(), ubicaciones_iniciales.end());

    int distancia_objetivo = (total_puestos - 1) / (total_vacas - 1);
    int num_distancias_extra = total_puestos - (total_vacas - 1) * distancia_objetivo;

    vector<vector<int>> tabla_costos(total_vacas + 1, vector<int>(num_distancias_extra + 1, LIMITE_ALTO));
    tabla_costos[1][1] = abs(ubicaciones_iniciales[0] - 1);

    for (int i = 2; i <= total_vacas; ++i) {
        for (int j = 0; j <= min(num_distancias_extra, i); ++j) {
            int posicion_destino = distancia_objetivo * (i - 1) + j;
            if (j > 0) {
                tabla_costos[i][j] = min(tabla_costos[i][j], tabla_costos[i-1][j] + abs(ubicaciones_iniciales[i-1] - posicion_destino));
                tabla_costos[i][j] = min(tabla_costos[i][j], tabla_costos[i-1][j-1] + abs(ubicaciones_iniciales[i-1] - posicion_destino));
            } else {
                tabla_costos[i][j] = tabla_costos[i-1][j] + abs(ubicaciones_iniciales[i-1] - posicion_destino);
            }
        }
    }

    cout << tabla_costos[total_vacas][num_distancias_extra] << endl;
    return 0;
}

Etiquetas: C++ USACO dynamic-programming sorting algorithms

Publicado el 7-3 17:25