/* Mars (IOI 1997) Copyright (C) 2001 Flavio Chierichetti This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Il programma si basa su un'euristica: massimizzare il numero di campioni raccolti da un VEM, toglierli dalla mappa e procedere nello stesso modo con i VEM rimanenti. Per massimizzare il numero di campioni raccolti da un singolo VEM, basta utilizzare la programmazione dinamica: infatti, per via delle restrizioni sul movimento, il massimo numero C(i,j) di campioni raccoglibili dalla posizionie (i,j) è dato da C(i,j) = max(C(i+1,j), C(i,j+1)) + (1 se c'è un campione in [i,j], 0 altr.), dove il massimo è tra le posizioni effettivamente esistenti. */ #include #define Libero 0 #define Inagibile 1 #define Roccia 2 #define getMax(a,b) (a) > (b) ? (a) : (b) enum { MaxC = 255 }; int N,P,Q; int Marte[MaxC+1][MaxC+1],NRocce[MaxC+1][MaxC+1]; /* Il +1 c'e' per permettere di indicizzare gli array da 1 a N invece che da 0 a N-1 */ void calcola(); int main() { int r,c,n,m; scanf(" %d %d %d",&N,&P,&Q); for ( r=1 ; r <= Q ; r++ ) for ( c=1 ; c <= P ; c++ ) scanf(" %d",Marte[r]+c); for ( n=1 ; n <= N ; n++ ) { calcola(); r = c = 1; while ( r < Q || c < P ) { Marte[r][c] = Libero; if ( r == Q ) m = 1; /* Est per forza */ else if ( c == P ) m = 0; /* Sud per forza */ else m = NRocce[r][c+1] > NRocce[r+1][c]; /* Est o Sud */ if ( m ) c++; else r++; printf("%d %d\n",n,m); } } return 0; } void calcola() { int r,c,Max; for ( r=Q ; r >= 1 ; r-- ) for ( c=P ; c >= 1 ; c-- ) { if ( Marte[r][c] == Inagibile ) { NRocce[r][c] = -1; continue; } if ( r == Q ) { if ( c == P ) /* ultima riga e ultima colonna */ Max = 0; else /* ultima riga ma non ultima colonna */ Max = NRocce[r][c+1]; } else if ( c == P ) { /* ultima colonna ma non ultima riga */ Max = NRocce[r+1][c]; } else /* altra casella */ Max = getMax(NRocce[r+1][c],NRocce[r][c+1]); if ( Marte[r][c] == Roccia && Max != -1 ) Max++; NRocce[r][c] = Max; } }