Advertisement
Hezov

Die hard - nerdarena

Jan 26th, 2025
31
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.85 KB | None | 0 0
  1. /// Complexitate O(n^2). Sper sa dea bine
  2. #include <fstream>
  3. #include <algorithm>
  4. using namespace std;
  5. ifstream cin("diehard.in");
  6. ofstream cout("diehard.out");
  7. #define from mat /// Fara asta -> memory limit.
  8. const int inf = 1e9, mxN = 1e3;
  9. short mat[mxN+1][mxN+1], pozTop[mxN+1], pozBottom[mxN+1];;
  10. int dp[mxN+1][mxN+1], top[mxN+2], bottom[mxN+2];
  11. int main()
  12. {
  13.     int n, m;
  14.     cin >> n >> m;
  15.     for(int i = 1;i<=n;i++)
  16.         for(int j = 1;j<=m;j++)
  17.             cin >> mat[i][j];
  18.     /// Cazuri de baza.
  19.     for(int i = 1;i<=n;i++)
  20.         dp[i][1] = mat[i][1];
  21.     for(int i = 1;i<=n;i++)
  22.         for(int j = 2;j<=m;j++)
  23.             dp[i][j] = inf;
  24.  
  25.     /// Completeam restul dinamicii.
  26.     /// Ideea este ca un caz in care mergem mai intai
  27.     /// intr-o directie si apoi invers nu poate fi optim. ( sus -> jos)
  28.  
  29.     for(int j = 2;j<=m;j++)
  30.     {
  31.         ///Resetam tablourile top si bottom.
  32.         for(int i = 1;i<=n;i++)
  33.             top[i] = bottom[i] = inf, pozTop[i] = pozBottom[i] = -1;
  34.         /// Calculam top.
  35.         pozTop[1] = 1;
  36.         top[1] = mat[1][j] + dp[1][j-1];
  37.         for(int i = 2;i<=n;i++)
  38.         {
  39.             int A = top[i-1] + mat[i][j];
  40.             int B = mat[i][j] + dp[i][j-1];
  41.             if(A < B) pozTop[i] = pozTop[i-1];
  42.             else pozTop[i] = i;
  43.             top[i] = min(A,B);
  44.         }
  45.         /// Calculam bottom.
  46.         pozBottom[n] = n;
  47.         bottom[n] = mat[n][j] + dp[n][j-1];
  48.         for(int i = n - 1; i > 0; i--)
  49.         {
  50.             int A = bottom[i+1] + mat[i][j];
  51.             int B = mat[i][j] + dp[i][j-1];
  52.             if(A < B) pozBottom[i] = pozBottom[i+1];
  53.             else pozBottom[i] = i;
  54.             bottom[i] = min(A,B);
  55.         }
  56.         /// Folosind vectorii top si bottom construim coloana j de dp.
  57.         for(int i = 1;i<=n;i++)
  58.         {
  59.             int A = dp[i][j-1] + mat[i][j] , B = top[i], C = bottom[i];
  60.             if(A < B && A < C)
  61.                 from[i][j] = i;
  62.             else if(B < A && B < C)
  63.                 from[i][j] = pozTop[i];
  64.             else from[i][j] = pozBottom[i];
  65.             dp[i][j] = min(A, min(B,C));
  66.         }
  67.     }
  68.     int pozX = -1, pozY = m;
  69.     int sol = 2e9;
  70.     for(int i = 1;i<=n;i++)
  71.     {
  72.         if(dp[i][m] < sol)
  73.             sol = dp[i][m], pozX = i;
  74.     }
  75.     /// Reconstruim traseul
  76.     string traseu = ""; int linieStart = -1;
  77.     while(pozY > 1)
  78.     {
  79.         if(pozY == 2) linieStart = from[pozX][pozY];
  80.         //cout << from[pozX][pozY] << ' ' ;
  81.         int next_line = from[pozX][pozY];
  82.         while(pozX != next_line)
  83.         {
  84.             if(pozX > next_line)
  85.                 traseu+='S', pozX--;
  86.             else traseu+='N', pozX++;
  87.         }
  88.         traseu+='E';
  89.         pozY--;
  90.     }
  91.     reverse(traseu.begin(),traseu.end());
  92.     cout << sol << '\n' << linieStart << ' ' << traseu;
  93. }
  94.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement