Cod sursa(job #2975216)

Utilizator NeacsuMihaiNeacsu Mihai NeacsuMihai Data 5 februarie 2023 20:47:32
Problema Ferma2 Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.46 kb
/*
    Un comentariu extraordinar de useful:
    Ideea corecta de rezolvare pleaca de la o observatie: "Daca vindem intr-o zi un teren, atunci Ion
    ramane tot cu un triunghi dreptunghic isoscel, dar cu catetele mai mici cu 1." Astfel dupa k zile el
    ramane cu un triunghi dreptughic isoscel cu catetele de lungime n - k, care, pentru ca profitul sa fie maxim, trebuie sa aiba
    valoare minima. De fapt problema se reduce la aflarea unui triunghi dreptunghic isoscel de cateta n - k pentru care suma este
    minima( care merge cu o dinamica).

    Eh, de fapt nu as numi-o o dinamica totusi, e efectiv o suma

    suma[i][j] = suma valorilor din dreptunghiul cu catetele de dimensiune N - K, care are coltul din dreapta jos in (i, j)
*/
#include <bits/stdc++.h>

using namespace std;

ifstream fin ("ferma2.in");
ofstream fout ("ferma2.out");

constexpr int NMAX = 1000; ///o mie

int v[NMAX + 1][NMAX + 1];
int sp[NMAX + 1][NMAX + 1];
int suma[NMAX + 1][NMAX + 1];

inline sumaCap(int x, int y){
    if(x >= 0 && y >= 0){
        return sp[x][y];
    }
    return 0;
}

inline int giveS(int x1, int y1, int x2, int y2){
    return sumaCap(x2, y2) - sumaCap(x2, y1 - 1) - sumaCap(x1 - 1, y2) + sumaCap(x1 - 1, y1 - 1);
}

int main()
{
     int N, K;
     fin >> N >> K;
     int A = N - K;
     int sumaTotala = 0;

     for(int i = 1; i <= N; i++){
        for(int j = 1; j <= i; j++){
            fin >> v[i][j];
            sumaTotala += v[i][j];
        }
     }

     for(int i = 1; i <= N; i++){
        for(int j = 1; j <= i; j++){
            sp[i][j] = v[i][j] + sp[i][j - 1] + sp[i - 1][j] - sp[i - 1][j - 1];
        }
     }

    for(int i = 1; i <= N; i++){
        for(int j = 1; j <= i; j++){
            suma[i][j] = suma[i - 1][j - 1] - giveS(i - A, j - A, i - 1, j - A) + giveS(i, j - A + 1, i, j);
        }
    }


    int rezultat = 0;
    for(int i = 1; i <= N; i++){
        for(int j = 1; j <= i; j++){
            if(i - A + 1 >= 1 && j - A + 1 >= 1){
                int candidat = sumaTotala - suma[i][j];

                if(candidat > rezultat){
                    rezultat = candidat;
                }
            }
        }
    }

    fout << rezultat << "\n";

    /*
    for(int i = 1; i <= N; i++){
        for(int j = 1; j <= i; j++){
            printf("suma[ %d ][ %d ] = %d\n", i, j, suma[i][j]);
        }
        printf("\n");
    }
    printf("\n");
    */

    return 0;
}