USACO 3.3.4 range & 3.3.5 game1 解题报告
这两题都是DP,总体上没啥太大的难度。
range方程式: f[i][j] = min(f[i][j - 1], min(f[i - 1][j], f[i – 1][j - 1])) + 1;
game1方程式:f[i][j] = sum[i][j] – min(f[i][j - 1], f[i + 1][j]);
程序上也没啥好主意的……
range:
/* TASK:range LANG:C++ */ #include <iostream> #include <fstream> using namespace std; int f[251][251], count[251]; char a[251][251]; int n, ans; void init() { scanf("%d\n", &n); for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { scanf("%c", &a[i][j]); f[i][j] = (a[i][j] == '1'); } scanf("\n"); } } void solve() { for (int i = 1; i < n; i++) for (int j = 1; j < n; j++) if (a[i][j] == '1') { f[i][j] = min(f[i - 1][j - 1], min(f[i][j - 1], f[i - 1][j])) + 1; for (int k = 2; k <= f[i][j]; k++) count[k]++; ans = max(f[i][j], ans); } } void print() { for (int i = 2; i <= ans; i++) printf("%d %d\n", i, count[i]); } int main() { freopen("range.in", "r", stdin); freopen("range.out", "w", stdout); init(); solve(); print(); return 0; }
game1:
/* TASK:game1 LANG:C++ */ #include <iostream> #include <fstream> #include <climits> using namespace std; int n; int sum[101]; int f[101][101]; void init() { scanf("%d", &n); for (int i = 1; i <= n; i++) { int x; scanf("%d", &x); sum[i] = sum[i - 1] + x; f[i][i] = x; } } void solve() { for (int p = 1; p < n; p++) for (int i = 1; i <= n - p; i++) f[i][i + p] = sum[i + p] - sum[i - 1] - min(f[i + 1][i + p], f[i][i + p -1]); } void print() { printf("%d %d\n", f[1][n], sum[n] - f[1][n]); } int main() { freopen("game1.in", "r", stdin); freopen("game1.out", "w", stdout); init(); solve(); print(); return 0; }