usaco-camp

Short, concise solutions for problems from the USACO camp

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
  22. 22
  23. 23
  24. 24
  25. 25
  26. 26
  27. 27
  28. 28
  29. 29
  30. 30
  31. 31
  32. 32
  33. 33
  34. 34
  35. 35
  36. 36
  37. 37
  38. 38
  39. 39
  40. 40
  41. 41
  42. 42
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

ll t[303][303], dp[303][303][303];

int main() {
	int N, M, K;
	cin >> N >> M >> K;
	for (int i = 0; i < N; ++i) {
		for (int j = 0; j < M; ++j) cin >> t[i][j];
	}

	memset(dp, '?', sizeof dp);
	memset(dp[0], 0, sizeof dp[0]);
	for (int i = 0; i < N; ++i) {
		for (int j = 0; j < M; ++j) {
			for (int k = 0; k < M; ++k) {
				if (j != k) dp[i + 1][j][k] = min(dp[i][j][k] + t[i][j] + t[i][k], dp[i + 1][j][k]);
			}
		}
		for (int j = 0; j < M; ++j) {
			for (int k = 0; k < M; ++k) {
				if (j > 0 && j - 1 != k) dp[i + 1][j][k] = min(dp[i + 1][j - 1][k] + K, dp[i + 1][j][k]);
				if (k > 0 && j != k - 1) dp[i + 1][j][k] = min(dp[i + 1][j][k - 1] + K, dp[i + 1][j][k]);
			}
		}
		for (int j = M - 1; j >= 0; --j) {
			for (int k = M - 1; k >= 0; --k) {
				if (j < M - 1 && j + 1 != k) dp[i + 1][j][k] = min(dp[i + 1][j + 1][k] + K, dp[i + 1][j][k]);
				if (k < M - 1 && j != k + 1) dp[i + 1][j][k] = min(dp[i + 1][j][k + 1] + K, dp[i + 1][j][k]);
			}
		}
	}
	ll ans = 1e18;
	for (int i = 0; i < M; ++i) {
		for (int j = 0; j < M; ++j) {
			if (i != j) ans = min(dp[N][i][j], ans);
		}
	}
	cout << ans << '\n';
}