1>不相交区间区间问题
活动安排
求不相交区间个数
这里选择将r作为限制,以达到全局最优的目的
策略:选择对后面影响小的
#include<cstdio> #include<cstdlib> #include<algorithm> using namespace std; int n; const int N=1003; struct node { int l,r; bool operator < (const node & o) { return r==o.r?l<o.l:r<o.r; } }d[N]; int main() { scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d%d",&d[i].l ,&d[i].r ); sort(d+1,d+n+1); int cnt=1,nw=d[1].r ; for(int i=2;i<=n;i++) if(d[i].l >=nw) cnt++,nw=d[i].r ; printf("%d\n",cnt); return 0; }
2>区间选点问题
尽量让每个点给多个区间使用,即尽量在重叠区域种树
因为点的分布可能是:
l 0 0 0 1 1 0 1 1 0 r
所以只能把每个点的数记在每个点上,然后每个点只能种一次,所以用us记录
#include<cstdio> #include<cstdlib> #include<algorithm> using namespace std; int m,n; const int N=5003; struct node { int l,r,nd; bool operator < (const node & o) { return r==o.r?l<o.l:r<o.r; } }d[N]; int tr[30003]; bool us[30003]; int lowbit(int x) { return x&(-x); } void add(int x) { for(;x<=m;x+=lowbit(x)) tr[x]++; } int find(int l,int r) { int ans=0; for(;r;r-=lowbit(r)) ans+=tr[r]; for(;l;l-=lowbit(l)) ans-=tr[l]; return ans; } int main() { scanf("%d%d",&m,&n); for(int i=1;i<=n;i++) scanf("%d%d%d",&d[i].l ,&d[i].r ,&d[i].nd ); sort(d+1,d+n+1); int cnt=0; for(int i=1;i<=n;i++) { int t=d[i].nd - find(d[i].l -1,d[i].r ); if(t>0) { cnt+=t; while(t--) { while(us[d[i].r ]) d[i].r --; add(d[i].r ),us[d[i].r ]=true; } } } printf("%d\n",cnt); return 0; }
未完待续