USACO 3.4.4 rockers & 4.1.1 nuggets 解题报告
rockers是USACO一道很经典的动态规划,这个题其实是可以优化状态的。将状态表示中的一部分记录到状态的最优解中,从而实现将空间和空间都降一维的目的。
nuggets这个题判别几个特殊情况后就是个裸的背包了。
这两题都不难,均为1A。
rockers:
/* TASK:rockers LANG:C++ */ #include <iostream> #include <fstream> #include <climits> using namespace std; int a[21]; int f[21][21][21]; int n, t, m; void init() { scanf("%d%d%d", &n, &t, &m); for (int i = 1; i <= n; i++) scanf("%d", &a[i]); } void solve() { for (int i = 1; i <= n; i++) for (int j = 1; j <= m; j++) for (int k = 0; k <= t; k++) if (k < a[i]) f[i][j][k] = max(f[i - 1][j][k], f[i][j - 1][t]); else f[i][j][k] = max(f[i - 1][j][k - a[i]], f[i - 1][j - 1][t]) + 1; } void print() { printf("%d\n", f[n][m][t]); } int main() { freopen("rockers.in", "r", stdin); freopen("rockers.out", "w", stdout); init(); solve(); print(); return 0; }
nuggets:
/* TASK:nuggets LANG:C++ */ #include <iostream> #include <fstream> #include <algorithm> using namespace std; int a[11]; bool f[100000]; int n, m; bool flag; int gcd(int x, int y) { if (0 == y) return x; return gcd(y, x % y); } void init() { scanf("%d", &n); for (int i = 0; i < n; i++) { scanf("%d", &a[i]); if (1 == a[i]) { flag = 1; return; } } if (n == 1) {flag = 1; return;} sort(a, a + n); } void solve() { if (flag) return; int tmp = a[0]; for (int i = 1; i < n; i++) tmp = gcd(tmp, a[i]); if (tmp != 1) {flag = 1; return;} m = a[n - 1] * a[n - 2] / gcd(a[n - 1], a[n - 2]); f[0] = 1; for (int i = 0; i < n; i++) for (int j = a[i]; j <= m; j++) if (f[j - a[i]]) f[j] = 1; } void print() { if (flag) printf("0\n"); for (int i = m; i > 0; i--) if (!f[i]) { printf("%d\n", i); break; } } int main() { freopen("nuggets.in", "r", stdin); freopen("nuggets.out", "w", stdout); init(); solve(); print(); return 0; }