链接:
#include <stdio.h>
int main()
{
puts("转载请注明出处[vmurder]谢谢");
puts("网址:blog.csdn.net/vmurder/article/details/44979323");
}
题解:
一句话 (a,b) 可以理解成一个线段 (a,n?b] 。
然后排个序去下重,最后一个线段的权值 x 就是表示 这 x 人互不冲突,一起算。
然后动态规划求若干条不相交线段的权值最大值,最后用总人数减去就行了。
fi 表示有 i 人时最大权值。
fseqi→ r=max ( fsi→ r , fsi→ l+si→ x );
然后一个线段的权值不能单纯看有多少人说的相同,因为可以有100个人都说了同一个线段 (a,a+1] ,那么显然这个线段的权值不是100,而是1。
代码:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 101000
using namespace std;
int n,m,p;
struct Eli
{
int l,r,x;
void read()
{
scanf("%d%d",&l,&r);
r=n-r;
}
bool operator < (const Eli &A)const
{return r==A.r?l<A.l:r<A.r;}
}s[N];
int f[N];
int main()
{
freopen("test.in","r",stdin);
int i;
scanf("%d",&n);
for(i=1;i<=n;i++)s[i].read();
sort(s+1,s+n+1);
for(i=1;i<=n;i++)
{
if(s[i].l>=s[i].r)continue;
if(s[i].l!=s[i-1].l||s[i].r!=s[i-1].r)
s[++m].l=s[i].l,s[m].r=s[i].r,s[m].x=1;
else s[m].x++;
}
for(i=1;i<=m;i++)
{
while(p<s[i].l)f[p+1]=max(f[p+1],f[p]),p++;
s[i].x=min(s[i].x,s[i].r-s[i].l);
f[s[i].r]=max(f[s[i].r],f[s[i].l]+s[i].x);
}
while(p<s[m].r)f[p+1]=max(f[p+1],f[p]),p++;
printf("%d\n",n-f[s[m].r]);
return 0;
}
时间: 2024-11-06 07:36:26