TYVJ 1072 bomb 解题报告
这题第一问就是最长上升序列,不解释。
第二问说一下,首先,如果i可以打到j,那就把i,j之间加一条边,然后搜最大匹配。最大匹配出来的结果是边数的结果,然后用节点数减去变数就是有多少条链(画图看),感觉好像生物里的氨基酸——多肽。
代码:
#include <stdio.h> #include <string.h> #include <stdlib.h> #define max(a, b) ((a)>(b)?(a):(b)) struct num{ int x, y, z; }num[1000]; int f[1000]; int ans, n; int map[1000][1000]; int used[1000]; int from[1000]; int find(int k) { int i; for(i = 0; i < n; i++){ if(map[k][i] && !used[i]){ used[i] = 1; if(from[i] == -1 || find(from[i])){ from[i] = k; return 1; } } } return 0; } int com(const void *a, const void *b) { struct num *i = (struct num *)a, *j = (struct num *)b; return i->x - j->x; } int main(int argc, char **argv) { int i, j; scanf("%d", &n); for(i = 0; i < n; i++){ scanf("%d%d%d", &num[i].x, &num[i].y, &num[i].z); } qsort(num, n, sizeof(struct num), com); for(i = 0; i < n; i++){ f[i] = 1; for(j = 0; j < i; j++){ if(num[i].x > num[j].x && num[i].y > num[j].y && num[i].z > num[j].z){ f[i] = max(f[i], f[j] + 1); } } ans = max(ans, f[i]); } printf("%d\n", ans); for(i = 0; i < n; i++){ for(j = 0; j < n; j++){ if(num[i].x < num[j].x && num[i].y < num[j].y && num[i].z < num[j].z){ map[j][i] = 1; } } } for(i = 0; i < n; i++){ from[i] = -1; } for(i = ans = 0; i < n; i++){ memset(used, 0, sizeof(used)); if(find(i)){ ans++; } } printf("%d\n", n - ans); return 0; }