题目:
分析:
对于第一问,我们可以通过
d
p
dp
dp求解,设
f
i
f_i
fi为当之前的方案最后拦截到的导弹的编号,那么我们的
f
j
=
m
a
x
{
f
i
}
+
1
f_j=max\{f_i\}+1
fj=max{fi}+1
可是第二问就没那么容易了
小编的方法是将问题转化为一个图,然后求最小覆盖
而求最小覆盖的方法就是通过创建一个二分图,然后跑匈牙利算法求解
代码:
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<set>
#include<queue>
#include<vector>
#include<map>
#include<list>
#include<ctime>
#include<iomanip>
#include<string>
#include<bitset>
#include<deque>
#include<set>
#define LL long long
#define ch cheap
using namespace std;
inline LL read() {
LL d=0,f=1;char s=getchar();
while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
while(s>='0'&&s<='9'){d=d*10+s-'0';s=getchar();}
return d*f;
}
int max(int x,int y){return x>y?x:y;}
const int N=1001;
struct node
{
int x,y,z;
}a[N];
int ans;
int b[N<<1][N];
int f[N<<1];
bool bz[N<<1];
bool cmp(node x,node y) {return x.x<y.x;}
bool HZB_shi_erzi(int x)
{
for(int i=1;i<=b[x][0];i++)
if(!bz[b[x][i]])
{
bz[b[x][i]]=true;
if(!f[b[x][i]] || HZB_shi_erzi(f[b[x][i]]))
{
f[b[x][i]]=x;
return true;
}
}
return false;
}
int main()
{
freopen("missile.in","r",stdin);
freopen("missile.out","w",stdout);
int n=read();
for(int i=1;i<=n;i++) a[i].x=read(),a[i].y=read(),a[i].z=read();
sort(a+1,a+1+n,cmp);
for(int i=1;i<=n;i++)
for(int j=f[i]=1;j<i;j++)
if(a[j].y<a[i].y&&a[j].z<a[i].z)
{
f[i]=max(f[i],f[j]+1);
b[j<<1][++b[j<<1][0]]=i<<1|1;
}
for(int i=1;i<=n;i++)
{
if(f[i]>ans) ans=f[i];
f[i]=0;
}
printf("%d\n",ans),ans=0;
for(int i=2;i<=n<<1;i+=2)
{
memset(bz,false,sizeof(bz));
if(HZB_shi_erzi(i)) ans++;
}
printf("%d",n-ans);
return 0;
}