标签:net eof pua stdin bcf 为什么 pen tco 分享
如果没思路可以先根据样例考虑几种显然不成立的情况,比如总共有n个人,但是某小朋友说比他大的有n+1个,很明显他就没吃药,这种情况就是l+r>=n(如果不取等的话说话的人就没了,l表示比他低的人,r表示比他高的人)这是一种;但是这样就行了吗?????肯定不行。在考虑一些比较鬼畜的情况,如果要比较好的理解矛盾我们可以考虑对信息进行初步转换:l r表示把1-n分成了三个区间,比当前人大,小和相等。嗯。。其实对于一个确定的任意l,考虑一种客观的请况:我们可以确定该人的三个区间。找到了对于单一的确定性,那么冲突应该就在这里。所以我们考虑区间的冲突。
好吧,其实我上一段说的都是废话,你不理解也没关系。但是通过上面的分析,你应该可以感觉得到,可以用线段覆盖来解决这个问题,考虑三段区间,只有与当前人分数相等的区间才能在两个区间交叉是矛盾,科学点说,对于l1,r1,l2,r2;
可以性成分 的六个区间,考虑与两个人相等的两个区间如果相交,就会变成如图的1 2 3 三部分,第一个人得2 3区间内分数相同,同理1 2区间内分数相同。所以1 3区间内分数相同。!!!那为什么1 3区间没有连在一起嘞。真想只有一个:就是这两个人之间一定有人在撒谎。那我们取一个就行了。
到此,问题即:求连续区间内的线段不重合的的最大权值,(顺便说一下,当,某一区间的人数超过其长度是,就一定有些人在说谎,我们考虑去掉多余的人,将权值给成区间长度就行了)
定义f[j]为到点j之前的最大权值。更新的位置是每条线段的右端点,所以我们考虑对右端点排序,然后写出以下方程:
结束了,注意前面提到的两条判断即可;
1 #include <cstdio> 2 #include <iostream> 3 #include <algorithm> 4 #define N 100010 5 #define Run(i,l,r) for(int i=l;i<=r;i++) 6 #define Don(i,l,r) for(int i=l;i>=r;i--) 7 using namespace std; 8 struct node{ 9 int l,r,w; 10 }a[N],b[N]; 11 int n,f[N]; 12 bool cmp(node a,node b){ 13 if (a.r==b.r) return a.l<b.l; 14 else return a.r<b.r; 15 } 16 int main() 17 { //freopen("explore.in","r",stdin); 18 //freopen("explore.out","w",stdout); 19 cin>>n; 20 int cnt=0; 21 Run(i,1,n){int l,r; 22 scanf("%d%d",&l,&r); 23 if (l+r<n) 24 {a[++cnt].l=l+1; 25 a[cnt].r=n-r; 26 a[cnt].w=1; 27 } 28 } 29 sort(a+1,a+cnt+1,cmp); 30 int temp=0; 31 Run(i,1,cnt){ 32 if (a[i].l==a[i-1].l&&a[i].r==a[i-1].r) a[i].w+=a[i-1].w; 33 if (a[i].r!=a[i+1].r||a[i].l!=a[i+1].l) {a[i].w=min(a[i].w,a[i].r-a[i].l+1); b[++temp]=a[i];} 34 } 35 Run(i,1,temp) 36 {f[b[i].r]=max(f[b[i].r],f[b[i].l-1]+b[i].w); 37 Run(j,b[i].r+1,b[i+1].r) f[j]=f[j-1]; 38 } 39 cout<<n-f[b[temp].r]<<endl; 40 //Run(i,1,n) cout<<f[i]<<" "; 41 return 0; 42 }
标签:net eof pua stdin bcf 为什么 pen tco 分享
原文地址:http://www.cnblogs.com/AUSTIN-tkys/p/7625209.html