Ranking (as of 2014-11-05): 30 out of 594
Language: C++
/*
UVa 10913 - Walking on a Grid
To build using Visual Studio 2012:
cl -EHsc -O2 UVa_10913_Walking_on_a_Grid.cpp
*/
#include <iostream>
#include <algorithm>
#include <limits>
using namespace std;
const int infinite = numeric_limits<int>::min();
const int N_max = 75, k_max = 5;
int grid[N_max][N_max];
int paths[N_max][N_max][k_max + 1];
// paths[i][j][k] is the max. sum of integers to square (i, j) with
// k negative integers, or infinite if it is impossible to reach the square
int paths_from_left[N_max][k_max + 1], paths_from_right[N_max][k_max + 1];
#ifdef DEBUG
void print_paths(int N, int k, int r)
{
for (int c = 0; c < N; c++) {
cout << '[';
for (int i = 0; i <= k; i++)
cout << paths[r][c][i] << ((i < k) ? " " : "] ");
}
cout << endl;
}
void print_paths(int N, int k, int p[N_max][k_max + 1])
{
for (int c = 0; c < N; c++) {
cout << '[';
for (int i = 0; i <= k; i++)
cout << p[c][i] << ((i < k) ? " " : "] ");
}
cout << endl;
}
#endif
int main()
{
for (int case_nr = 1; ; case_nr++) {
int N, k;
cin >> N >> k;
if (!N && !k)
break;
for (int r = 0; r < N; r++)
for (int c = 0; c < N; c++) {
cin >> grid[r][c];
for (int i = 0; i <= k; i++)
paths[r][c][i] = infinite;
}
for (int i = 0, j = (grid[0][0] < 0) ? 1 : 0; i + j <= k; i++)
paths[0][0][i + j] = grid[0][0];
for (int c = 1; c < N; c++) // the first row
for (int i = 0, j = (grid[0][c] < 0) ? 1 : 0; i + j <= k; i++)
if (paths[0][c - 1][i] != infinite)
paths[0][c][i + j] = paths[0][c - 1][i] + grid[0][c];
#ifdef DEBUG
print_paths(N, k, 0);
#endif
for (int r = 1; r < N; r++) { // between the second and the last row
for (int c = 0; c < N; c++)
for (int i = 0; i <= k; i++)
paths_from_left[c][i] = paths_from_right[c][i] = infinite;
for (int c = 0; c < N; c++)
for (int i = 0, j = (grid[r][c] < 0) ? 1 : 0; i + j <= k; i++) {
int p = infinite;
if (r)
p = max(p, paths[r - 1][c][i]);
if (c)
p = max(p, paths_from_left[c - 1][i]);
if (p != infinite)
paths_from_left[c][i + j] = p + grid[r][c];
}
for (int c = N - 1; c >= 0; c--)
for (int i = 0, j = (grid[r][c] < 0) ? 1 : 0; i + j <= k; i++) {
int p = infinite;
if (r)
p = max(p, paths[r - 1][c][i]);
if (c < N - 1)
p = max(p, paths_from_right[c + 1][i]);
if (p != infinite)
paths_from_right[c][i + j] = p + grid[r][c];
}
#ifdef DEBUG
print_paths(N, k, paths_from_left);
print_paths(N, k, paths_from_right);
#endif
for (int c = 0; c < N; c++)
for (int i = 0; i <= k; i++)
paths[r][c][i] = max(paths_from_left[c][i], paths_from_right[c][i]);
#ifdef DEBUG
print_paths(N, k, r);
#endif
}
int max_path = infinite;
for (int i = 0; i <= k; i++)
max_path = max(max_path, paths[N - 1][N - 1][i]);
cout << "Case " << case_nr << ": ";
if (max_path != infinite)
cout << max_path << endl;
else
cout << "impossible\n";
}
return 0;
}
No comments:
Post a Comment