HDU 2016.11.12 做题感想
细数一下这两天做过的值得总结的一些题Orz......
HDU 2571 简单dp,但是一开始WA了一发。原因很简单:没有考虑仔细。
如果指向该点的所有点权值都为负数,那就错了(我一开始默认初始值为0)
这是非常基础的典型DAG模型,好久不做,手明显生了……
1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 #define REP(i,n) for(int i(0); i < (n); ++i) 6 #define rep(i,a,b) for(int i(a); i <= (b); ++i) 7 #define dec(i,a,b) for(int i(a); i >= (b); --i) 8 #define for_edge(i,x) for(int i = H[x]; i; i = X[i]) 9 10 #define LL long long 11 #define ULL unsigned long long 12 #define MP make_pair 13 #define PB push_back 14 #define FI first 15 #define SE second 16 #define INF 1 << 30 17 18 const int N = 100000 + 10; 19 const int M = 10000 + 10; 20 const int Q = 1000 + 10; 21 const int A = 30 + 1; 22 23 int f[A][Q], c[A][Q]; 24 int T; 25 int n, m; 26 27 int main(){ 28 #ifndef ONLINE_JUDGE 29 freopen("test.txt", "r", stdin); 30 freopen("test.out", "w", stdout); 31 #endif 32 33 scanf("%d ", &T); 34 REP(Case, T){ 35 scanf("%d %d ", &n, &m); 36 memset(f, 0, sizeof f); 37 rep(i, 1, n) rep(j, 1, m) scanf("%d ", &c[i][j]); 38 f[1][1] = c[1][1]; 39 rep(i, 2, m){ 40 int now = f[1][i - 1]; 41 rep(j, 1, i >> 1) if (i % j == 0) now = max(now, f[1][j]); 42 f[1][i] = c[1][i] + now; 43 } 44 45 rep(i, 2, n) f[i][1] = c[i][1] + f[i - 1][1]; 46 rep(i, 2, n) rep(j, 2, m){ 47 int now = f[i][j - 1]; 48 rep(k, 1, j >> 1) if (j % k == 0) now = max(now, f[i][k]); 49 now = max(now, f[i - 1][j]); 50 f[i][j] = c[i][j] + now; 51 } 52 //rep(i, 1, n){ rep(j, 1, m) printf("%d ", f[i][j]); putchar(10);} 53 printf("%d\n", f[n][m]); 54 } 55 56 57 58 return 0; 59 60 }
还有就是记忆化搜索,很裸的一道题。 HDU1579
题目也说了大数据时直接递归会超时,所以除了记忆化搜索,别无选择。
1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 #define REP(i,n) for(int i(0); i < (n); ++i) 6 #define rep(i,a,b) for(int i(a); i <= (b); ++i) 7 #define dec(i,a,b) for(int i(a); i >= (b); --i) 8 #define for_edge(i,x) for(int i = H[x]; i; i = X[i]) 9 10 #define LL long long 11 #define ULL unsigned long long 12 #define MP make_pair 13 #define PB push_back 14 #define FI first 15 #define SE second 16 #define INF 1 << 30 17 18 const int N = 100000 + 10; 19 const int M = 10000 + 10; 20 const int Q = 1000 + 10; 21 const int A = 30 + 1; 22 23 int f[A][A][A]; 24 int x, y, z; 25 26 int cal(int x, int y, int z){ 27 if (x <= 0 || y <= 0 || z <= 0) return 1; 28 if (x > 20 || y > 20 || z > 20) return f[20][20][20] = cal(20, 20, 20); 29 if (f[x][y][z] != -1) return f[x][y][z]; 30 if (x < y && y < z) return f[x][y][z] = cal(x, y, z - 1) + cal(x, y - 1, z - 1) - cal(x, y - 1, z); 31 else return f[x][y][z] = cal(x - 1, y, z) + cal(x - 1, y - 1, z) + cal(x - 1, y, z - 1) - cal(x - 1, y - 1, z - 1); 32 } 33 34 35 int main(){ 36 #ifndef ONLINE_JUDGE 37 freopen("test.txt", "r", stdin); 38 freopen("test.out", "w", stdout); 39 #endif 40 41 memset(f, -1, sizeof f); 42 while (~scanf("%d%d%d", &x, &y, &z)){ 43 if (x == -1 && y == -1 && z == -1) break; 44 printf("w(%d, %d, %d) = %d\n", x, y, z, cal(x, y, z)); 45 } 46 47 48 49 50 return 0; 51 52 }
还有一道并查集裸题……HDU1232
直接YY一个就A了……
1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 #define REP(i,n) for(int i(0); i < (n); ++i) 6 #define rep(i,a,b) for(int i(a); i <= (b); ++i) 7 #define dec(i,a,b) for(int i(a); i >= (b); --i) 8 #define for_edge(i,x) for(int i = H[x]; i; i = X[i]) 9 10 #define LL long long 11 #define ULL unsigned long long 12 #define MP make_pair 13 #define PB push_back 14 #define FI first 15 #define SE second 16 #define INF 1 << 30 17 18 const int N = 100000 + 10; 19 const int M = 10000 + 10; 20 const int Q = 1000 + 10; 21 const int A = 30 + 1; 22 23 int f[N]; 24 int n, m; 25 int x, y; 26 27 int getfather(int x){ return f[x] ? f[x] = getfather(f[x]) : x;} 28 29 int main(){ 30 #ifndef ONLINE_JUDGE 31 freopen("test.txt", "r", stdin); 32 freopen("test.out", "w", stdout); 33 #endif 34 35 while (~scanf("%d", &n), n){ 36 scanf("%d", &m); 37 memset(f, 0, sizeof f); 38 while (m--){ 39 scanf("%d%d", &x, &y); 40 int fa = getfather(x), fb = getfather(y); 41 if (fa != fb) f[fa] = fb; 42 } 43 44 int ans = 0; 45 rep(i, 1, n - 1) rep(j, i + 1, n){ 46 int fa = getfather(i), fb = getfather(j); 47 if (fa != fb){ 48 f[fa] = fb; 49 ++ans; 50 } 51 if (ans >= n) break; 52 } 53 54 printf("%d\n", ans); 55 } 56 57 58 59 return 0; 60 61 }
剩下的一些水题都不好意思拿出来……之后要加大难度了……
The End.