#4:初学者之身——5
Joyoi Mobile Service,第一维:阶段,第几时刻;第二第三维:不安定因素,两个服务员的位置;省略第四维:肯定在p[i-1]。
1 #include <bits/stdc++.h> 2 using namespace std; 3 #define rep(i, a, b) for (int i = a; i <= b; i++) 4 #define inf 0x3f3f3f3f 5 6 int n, m; 7 int c[210][210], p[1010]; 8 int f[2][210][210]; 9 10 int main() { 11 cin >> n >> m; 12 rep(i, 1, n) 13 rep(j, 1, n) 14 cin >> c[i][j]; 15 rep(i, 1, m) cin >> p[i]; 16 p[0] = 3; 17 18 memset(f, 0x3f, sizeof(f)); 19 f[0][1][2] = 0; 20 21 rep(i, 1, m) 22 rep(x, 1, n) 23 rep(y, 1, n) { 24 if (x != p[i-1] && y != p[i-1] && f[i-1&1][x][y] != inf) { 25 int z = p[i-1]; 26 if (x != p[i] && y != p[i]) f[i&1][x][y] = min(f[i&1][x][y], f[i-1&1][x][y] + c[z][p[i]]); 27 if (y != p[i] && z != p[i]) f[i&1][y][z] = min(f[i&1][y][z], f[i-1&1][x][y] + c[x][p[i]]); 28 if (x != p[i] && z != p[i]) f[i&1][x][z] = min(f[i&1][x][z], f[i-1&1][x][y] + c[y][p[i]]); 29 f[i-1&1][x][y] = inf; 30 } 31 } 32 33 int ans = inf; 34 rep(x, 1, n) 35 rep(y, 1, n) 36 ans = min(ans, f[m&1][x][y]); 37 cout << ans << endl; 38 39 return 0; 40 }
洛谷1006,第一维:阶段,走到第几步;第二第三维:不安定因素,结尾位置;省略四维五维:有x坐标有步长可直接求y坐标。另外,一个格子只能走一次等价于走过一次还能走只不过值变成了0,会导致不如其他路线优秀。
1 #include <bits/stdc++.h> 2 using namespace std; 3 #define maxn 55 4 #define rep(i, a, b) for (int i = a; i <= b; i++) 5 6 int m, n; 7 int a[maxn][maxn], f[2][maxn][maxn]; 8 9 int main() { 10 cin >> m >> n; 11 rep(i, 1, m) rep(j, 1, n) cin >> a[i][j]; 12 13 rep(i, 0, n+m-3) { 14 int st = max(i+2-n, 1); 15 int ed = min(i+1, m); 16 rep(j, st, ed) 17 rep(k, st, ed) { 18 if (j == k) { 19 f[i+1&1][j][k] = max(f[i+1&1][j][k], f[i&1][j][k] + a[j][i+3-j]);//right 20 f[i+1&1][j+1][k+1] = max(f[i+1&1][j+1][k+1], f[i&1][j][k] + a[j+1][i+2-j]);//down 21 } else { 22 f[i+1&1][j][k] = max(f[i+1&1][j][k], f[i&1][j][k] + a[j][i+3-j] + a[k][i+3-k]);//right 23 f[i+1&1][j+1][k+1] = max(f[i+1&1][j+1][k+1], f[i&1][j][k] + a[j+1][i+2-j] + a[k+1][i+2-k]);//down 24 } 25 if (j + 1 == k) f[i+1&1][j+1][k] = max(f[i+1&1][j+1][k], f[i&1][j][k] + a[k][i+3-k]);//down&right 26 else f[i+1&1][j+1][k] = max(f[i+1&1][j+1][k], f[i&1][j][k] + a[k][i+3-k] + a[j+1][i+2-j]);//down&right 27 if (k + 1 == j) f[i+1&1][j][k+1] = max(f[i+1&1][j][k+1], f[i&1][j][k] + a[j][i+3-j]);//right&down 28 else f[i+1&1][j][k+1] = max(f[i+1&1][j][k+1], f[i&1][j][k] + a[j][i+3-j] + a[k+1][i+2-k]);//right&down 29 30 f[i&1][j][k] = 0; 31 } 32 } 33 34 cout << f[n+m-2 & 1][m][m]; 35 return 0; 36 }
CH Cookies,不能保证子结构后效性时说不定有排序贪心等性质,之后即可dp。下一步重头戏dp过程不会总结qwq
1 #include <bits/stdc++.h> 2 using namespace std; 3 #define R(a) scanf("%d", &a) 4 #define rep(i, a, b) for (int i = a; i <= b; i++) 5 6 int n, m; 7 int g[31], c[31], s[31]; 8 int f[31][5001], a[31][5001], b[31][5001], ans[31]; 9 10 inline bool cmp(int a, int b) { 11 return g[a] > g[b]; 12 } 13 14 void print(int n, int m) { 15 if (!n) return; 16 print(a[n][m], b[n][m]); 17 if (a[n][m] == n) { 18 rep(i, 1, n) ans[c[i]]++; 19 } else { 20 rep(i, a[n][m]+1, n) ans[c[i]] = 1; 21 } 22 } 23 24 int main() { 25 R(n), R(m); 26 rep(i, 1, n) R(g[i]), c[i] = i; 27 sort(c+1, c+1+n, cmp); 28 29 memset(f, 0x3f, sizeof(f)); 30 f[0][0] = 0; 31 32 rep(i, 1, n) { 33 s[i] = s[i-1] + g[c[i]]; 34 rep(j, i, m) { 35 f[i][j] = f[i][j-i]; 36 a[i][j] = i; 37 b[i][j] = j-i; 38 rep(k, 0, i-1) { 39 if (f[i][j] > f[k][j - (i-k)] + k * (s[i] - s[k])) { 40 f[i][j] = f[k][j - (i-k)] + k * (s[i] - s[k]); 41 a[i][j] = k; 42 b[i][j] = j - (i-k); 43 } 44 } 45 } 46 } 47 48 printf("%d\n", f[n][m]); 49 print(n, m); 50 rep(i, 1, n) printf("%d ", ans[i]); 51 52 return 0; 53 }
Joyoi数字组合,初学者背包裸题。
1 #include <cstdio> 2 3 int n, m, v[101]; 4 int f[10001]; 5 6 int main() { 7 scanf("%d%d", &n, &m); 8 for (int i = 1; i <= n; i++) 9 scanf("%d", &v[i]); 10 11 f[0] = 1; 12 for (int i = 1; i <= n; i++) 13 for (int j = m; j >= v[i]; j--) { 14 f[j] += f[j-v[i]]; 15 } 16 17 printf("%d", f[m]); 18 return 0; 19 }
BZOJ2914,有一点点像背包?就是得把题目的本质规律弄清楚就会了吧。
1 #include <cstdio> 2 #include <cctype> 3 #define ri readint() 4 #define gc getchar() 5 #define rep(i, a, b) for (int i = a; i <= b; i++) 6 #define W(a) printf("%d\n", a); 7 #define maxn 10005 8 9 int n, h[maxn]; 10 int ans; 11 int re[maxn], p, t; 12 bool f[maxn]; 13 14 inline int readint() { 15 int x = 0, s = 1, c = gc; 16 while (c <= 32) c = gc; 17 if (c == '-') s = -1, c = gc; 18 for (; isdigit(c); c = gc) 19 x = x * 10 + c - 48; 20 return x * s; 21 } 22 23 int main() { 24 n = ri; 25 rep(i, 1, n) h[i] = ri; 26 f[h[n]+1] = true; 27 28 rep(i, 0, h[n]+1) { 29 //height i is existed but not stable! 30 if (f[i] && i != h[t+1]) { 31 ans = h[t]; 32 break; 33 } 34 if (i == h[t+1]) { 35 if (!f[i]) {//add this as a base 36 re[++p] = h[t+1]; 37 f[i] = true; 38 } 39 t++; 40 } 41 if (f[i]) { 42 rep(j, 1, p) 43 f[re[j] + i] = true; 44 } 45 } 46 47 W(ans); 48 rep(i, 1, p) W(re[i]); 49 return 0; 50 }