比赛 20120615 评测结果 AAAAAAAAAA
题目名称 导弹拦截 最终得分 100
用户昵称 ZhouHang 运行时间 0.000 s
代码语言 C++ 内存使用 0.00 MiB
提交时间 2012-06-15 17:13:07
显示代码纯文本
/**
*Prob	: bomba
*Data	: 2012-6-15
*Sol	: ①动归
*Author : ZhouHang
*/

#include <cstdio>
#include <algorithm>
#include <cstring>

#define MaxN 1100

using namespace std;

struct node
{
	int x,y,z;
} a[MaxN];
int n,ans;
int f[MaxN];
//二分图
int maxnum;
int link[MaxN];
bool v[MaxN];
bool map[MaxN][MaxN];

bool cmp(int i,int j)
{
	if (a[i].x>a[j].x&&a[i].y>a[j].y&&a[i].z>a[j].z) return true;
	return false;
}

void Make_Graph()
{
	memset(map,false,sizeof(map));
	for (int i=1; i<=n; i++)
	 for (int j=1; j<=n; j++)
	 {
		if (i==j) continue;
		if (cmp(i,j)) map[i][j]=true;
	 }
}

bool find(int i)
{
	for (int k=1; k<=n; k++)
		if ( (!v[k])&&map[i][k] )
		{
			v[k]=true;
			if ( link[k]==0||find(link[k]) )
			{
				link[k]=i;
				return true;
			}
		}
	return false;
}

void work()
{
	maxnum=0;
	for (int i=1; i<=n; i++)
	{
		memset(v,false,sizeof(v));
		if ( find(i) ) maxnum++;
	}
}

void Swap(node &i,node &j)
{
	node c=i;
	i=j; j=c;
}

bool check(int i,int j)
{
	if (a[i].x>a[j].x) return true;
	if (a[i].x<a[j].x) return false;
	if (a[i].y>a[j].y) return true;
	if (a[i].y<a[j].y) return false;
	if (a[i].z>a[j].z) return true;
	return false;
}

int main()
{
	freopen("bomba.in","r",stdin);
	freopen("bomba.out","w",stdout);
	
	scanf("%d",&n);
	for (int i=1; i<=n; i++)
		scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].z);
	
	for (int i=1; i<=n; i++)
	 for (int j=i+1; j<=n; j++)
	 {
		if (check(i,j)) Swap(a[i],a[j]); 
	 }

	//first question
	for (int i=1; i<=n; i++) f[i]=1;
	ans=1;
	for (int x=2; x<=n; x++)
	 for (int y=1; y<x; y++)
		if (cmp(x,y))
		{
			f[x]=max(f[x],f[y]+1);
			if (f[x]>ans) ans=f[x];
		}
		
	printf("%d\n",ans);
	
	//sencond question
	Make_Graph();
	memset(link,0,sizeof(link));
	work();
	printf("%d\n",n-maxnum);
	
	fclose(stdin); fclose(stdout);
	return 0;
}