题目:
https://www.luogu.org/problem/show?pid=2093
拦截导弹?
每个物品有两个状态;
所以需要综合考虑;
开始的想法:将他们的和从小到大排序;
这样是不对的;
我们可以将其中一个价值排序,这样,我们就有了贪心的方向;
将另一个状态做拦截导弹就可以了;(显然?)
因为我们可以保证a数组是单调递减的;
能更新大的就更新大的,将小的留给后面更”需要”的物品; 学会善良地贪
方法二:
求最长下降子序列,它的长度即为答案;
证明:
假设已经有下降子序列: a、b;
存在一个c在在a,b后面;
if c > a , c可以在a组;
if c < a, c > b ,c可以在b组;
else c < b,c只能单独一组;
证毕……
当然,这里的a,b并不是固定不变的。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN=10001;
int n,tot;
struct hh
{
int x,y;
}ma[MAXN];
int a[MAXN];
bool cmp(hh a,hh b)
{
if(a.x==b.x) return a.y<b.y;//从小到大;
else return a.x<b.x;
}
void solve()
{
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d%d",&ma[i].x,&ma[i].y);
sort(ma+1,ma+n+1,cmp);
for(int i=1;i<=n;i++)
{
bool flag=0;
for(int j=1;j<=tot;j++)
{
if(a[j]<=ma[i].y)
{
a[j]=ma[i].y,flag=1;
break;
}
}
if(!flag) a[++tot]=ma[i].y;
}
cout<<tot<<endl;
return;
}
int main()
{
solve();
return 0;
}