-
D - Minimizing maximizer
- POJ - 1769
- 题意:给你一些区间,按照顺序选出最少的区间覆盖 1-n ,如果没有规定按顺序,可以贪心排序 选最少,
- 思路:按照给定的顺序进行DP转移。可以直接忽略掉dp数组,进行线段树状态的转移,除了
- 以1开头的区间直接更新最小值,其他的需要查询 当前区间左端点的最小值。然后进行+1 转移 , 转移过程是
- 更新这个区间所覆盖的区间的最小值。这种最值区间更新一定要注意 lazy 标记 与 最小值w 不要混用。
- 或者只用一个参数 按照染色思想进行处理
-
#include<cstdio> #include<algorithm> using namespace std; #define maxn 567891 #define inf 0x3f3f3f3f struct node { int l,r,w,lazy; } tree[maxn*4]; struct data { int head,tail; } a[maxn]; void up(int root) { tree[root].w=min(tree[root*2].w,tree[root*2+1].w); } void down(int root) { if(tree[root].lazy!=inf) { tree[root*2].lazy=min(tree[root].lazy,tree[root*2].lazy); tree[root*2+1].lazy=min(tree[root].lazy,tree[root*2+1].lazy); tree[root*2].w=min(tree[root].lazy,tree[root*2].w); tree[root*2+1].w=min(tree[root].lazy,tree[root*2+1].w); } } void bulid(int root,int l,int r) { tree[root].l=l; tree[root].r=r; tree[root].lazy=inf; tree[root].w=inf; if(l==r) return ; int mid=(l+r)/2; bulid(root*2,l,mid); bulid(root*2+1,mid+1,r); } void updata(int root,int l,int r,int ad) { if(tree[root].l==l&&tree[root].r==r) { tree[root].w=min(tree[root].w,ad); tree[root].lazy=min(tree[root].lazy,ad); return ; } down(root); int mid=(tree[root].l+tree[root].r)/2; if(l>mid) updata(root*2+1,l,r,ad); else if(r<=mid) updata(root*2,l,r,ad); else { updata(root*2+1,mid+1,r,ad); updata(root*2,l,mid,ad); } up(root); } int query(int root,int l) { if(tree[root].l==l&&tree[root].r==l) return tree[root].w; down(root); int mid=(tree[root].l+tree[root].r)/2; if(l>mid) query(root*2+1,l); else if(l<=mid) query(root*2,l); } int n,m,ans; int main() { scanf("%d%d",&n,&m); bulid(1,1,n); for(int i=1; i<=m; i++) { scanf("%d%d",&a[i].head,&a[i].tail); if(a[i].head==1)updata(1,a[i].head,a[i].tail,1); else { int pre=query(1,a[i].head); if(pre==inf)continue; else updata(1,a[i].head,a[i].tail,pre+1); } } ans=query(1,n); printf("%d\n",ans); return 0; }
D - Minimizing maximizer POJ - 1769 -DP-线段树
最新推荐文章于 2023-12-16 17:41:10 发布