Pagini recente » Cod sursa (job #426551) | Cod sursa (job #1733362) | Cod sursa (job #2883026) | Cod sursa (job #2430937) | Cod sursa (job #878003)
Cod sursa(job #878003)
#include <cstdio>
using namespace std;
//Matricea initiala
int m[502][502];
//Matricea dinamica, in care se vor tine rezultatele pentru un anumit rest al impartirii la 3
int din[502][502][3];
//Functia determina maximul dintre doua numere
int maxim(int a,int b)
{
if(a>b)
return a;
return b;
}
//Functia determina maximul dintre trei numere
int maxim(int a,int b,int c)
{
return maxim(maxim(a,b),c);
}
int main()
{
//Deschiderea fisierelor de intrare si iesire
freopen("maxtri.in","r",stdin);
freopen("maxtri.out","w",stdout);
//Se declara si citeste marimea matricei
int n;
scanf("%d",&n);
//Doua contoare
int i,j;
//Se citeste matricea initiala
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
scanf("%d",&m[i][j]);
//Prima linie si prima coloana din matricea dinamica pot fi initializate fara calcule prealabile folosind observatia
//ca exista un singur drum de la (1,1) pana la un element de pe prima linie sau de pe prima coloana
//Initial suma elementelor de pe prima linie este 0
int sum=0;
//Se initializeaza prima linie
for(i=1;i<=n;i++)
{
sum+=m[1][i];
din[1][i][sum%3]=sum;
}
//Initial suma elementelor de pe prima coloana este 0
sum=0;
//Se initializeaza prima coloana
for(i=1;i<=n;i++)
{
sum+=m[i][1];
din[i][1][sum%3]=sum;
}
//Se aplica relatia de recurenta pe restul matricei
for(i=2;i<=n;i++)
for(j=2;j<=n;j++)
{
if(m[i][j]%3==0)
{
//Atunci cand toti cei trei "predecesori" ai elementului curent din matricei
//sunt 0 inseamna ca nu exista un drum cu suma elementelor
//modulo 3 congruenta cu 0, deci nu trebuie sa modificam acest element al matricei
if(din[i][j-1][0]>0 || din[i-1][j][0]>0 || din[i-1][j-1][0]>0)
din[i][j][0]=maxim(din[i][j-1][0],din[i-1][j][0],din[i-1][j-1][0])+m[i][j];
//Analog
if(din[i][j-1][1]>0 || din[i-1][j][1]>0 || din[i-1][j-1][1]>0)
din[i][j][1]=maxim(din[i][j-1][1],din[i-1][j][1],din[i-1][j-1][1])+m[i][j];
//Analog
if(din[i][j-1][2]>0 || din[i-1][j][2]>0 || din[i-1][j-1][2]>0)
din[i][j][2]=maxim(din[i][j-1][2],din[i-1][j][2],din[i-1][j-1][2])+m[i][j];
}
else if(m[i][j]%3==1) //Analog, numai ca acum nu mai facem update pe aceleasi resturi, ci pe succesorul lor modulo 3
{
if(din[i][j-1][0]>0 || din[i-1][j][0]>0 || din[i-1][j-1][0]>0)
din[i][j][1]=maxim(din[i][j-1][0],din[i-1][j][0],din[i-1][j-1][0])+m[i][j];
if(din[i][j-1][1]>0 || din[i-1][j][1]>0 || din[i-1][j-1][1]>0)
din[i][j][2]=maxim(din[i][j-1][1],din[i-1][j][1],din[i-1][j-1][1])+m[i][j];
if(din[i][j-1][2]>0 || din[i-1][j][2]>0 || din[i-1][j-1][2]>0)
din[i][j][0]=maxim(din[i][j-1][2],din[i-1][j][2],din[i-1][j-1][2])+m[i][j];
}
else if(m[i][j]%3==2) //Analog, update pe resturi +2 (modulo 3)
{
if(din[i][j-1][0]>0 || din[i-1][j][0]>0 || din[i-1][j-1][0])
din[i][j][2]=maxim(din[i][j-1][0],din[i-1][j][0],din[i-1][j-1][0])+m[i][j];
if(din[i][j-1][1]>0 || din[i-1][j][1]>0 || din[i-1][j-1][1])
din[i][j][0]=maxim(din[i][j-1][1],din[i-1][j][1],din[i-1][j-1][1])+m[i][j];
if(din[i][j-1][2]>0 || din[i-1][j][2]>0 || din[i-1][j-1][2]>0)
din[i][j][1]=maxim(din[i][j-1][2],din[i-1][j][2],din[i-1][j-1][2])+m[i][j];
}
}
//Se afiseaza raspunsul problemei
printf("%d\n",din[n][n][0]);
return 0;
}