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;
}
posted @ 2011-07-15 15:10  zqynux  阅读(233)  评论(0编辑  收藏  举报