zoukankan      html  css  js  c++  java
  • POJ 1083

    期间用了DP(可能更有些贪心的思想的算法),但是一个细节错误一直没有考虑

    总体思路是这样的,按照每个区间的上界排序,然后从头到尾,定义(dv(i))为前i个最少需要的并行数量

    每次状态转移,从后向前搜索,每当发现当前区间(i)的下界比之前的区间的上界(seg[j].e)要小,说明二者必定重叠,直到遇到第一个不重叠的,把这第一个当作“父节点”,并更新父节点的上界。

    这种思路大体是对的,但是有一个缺陷,就是随着父节点不断更新,最早加入的子节点有可能不知道父节点的上界会长大到什么程度,导致之后一些节点实际上已经不能加入他们所在组,但是因为只看子节点看不到这些局限,这样就漏掉了好多情况。

    解决方案也显而易见,利用并查集

    #include <iostream>
    #include <algorithm>
    #include <queue>
    #include <string>
    #include <vector>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <string>
    #include <stack>
    #include <map>
    #include <set>
    using namespace std;
    
    const int maxn= 205;
    
    struct Seg
    {
    	int s, e;
    	Seg(int _s= 0, int _e= 0) : s(_s), e(_e) {}
    	bool operator < (const Seg &rhs) const
    	{
    		return e< rhs.e;
    	}
    }segs[maxn];
    int dv[maxn], fa[maxn];
    
    inline void Init(int n)
    {
    	for (int i= 0; i< n; ++i){
    		fa[i]= i;
    	}
    }
    inline int Find(int x)
    {
    	if (x== fa[x]){
    		return x;
    	}
    	return fa[x]= Find(fa[x]);
    }
    int main()
    {
    	int kase, n;
    	int a, b;
    	scanf("%d", &kase);
    
    	while (kase--){
    		scanf("%d", &n);
    		for (int i= 0; i< n; ++i){
    			scanf("%d %d", &a, &b);
    			if (a> b){
    				swap(a, b);
    			}
    			a= (a+1)>>1;
    			b= (b+1)>>1;
    			segs[i].s= a;
    			segs[i].e= b;
    		}
    		Init(n);
    		sort(segs, segs+n);
    
    		dv[0]= 1;
    		for (int i= 1; i< n; ++i){
    			int flag= 1;
    			for (int j= i-1; j>= 0; --j){
    				int fa_j= Find(j);
    				if (segs[i].s > segs[fa_j].e){
    					segs[fa_j].e= segs[i].e;
    					fa[i]= fa_j;
    					flag= 0;
    					break;
    				}
    			}
    			dv[i]= flag ? dv[i-1]+1 : dv[i-1];
    		}
    
    		printf("%d
    ", dv[n-1]*10);
    	}
    	return 0;
    }
    

    后面参考了别人的代码,发现另一种方法才更适合DP,完成之后记录如下

    #include <iostream>
    #include <algorithm>
    #include <queue>
    #include <string>
    #include <vector>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <string>
    #include <stack>
    #include <map>
    #include <set>
    using namespace std;
    
    const int maxn= 205;
    
    int ov[maxn];
    
    int main()
    {
    	int kase, n;
    	int a, b;
    	scanf("%d", &kase);
    
    	while (kase--){
    		scanf("%d", &n);
    		memset(ov, 0, sizeof(ov));
    		int ans= 0;
    		for (int i= 0; i< n; ++i){
    			scanf("%d %d", &a, &b);
    			if (a> b){
    				swap(a, b);
    			}
    			a= (a+1)>>1;
    			b= (b+1)>>1;
    			for (int i= a; i<= b; ++i){
    				++ov[i];
    				ans= max(ans, ov[i]);
    			}
    		}
    
    		printf("%d
    ", ans*10);
    	}
    	return 0;
    }
    
  • 相关阅读:
    Eclipse中的快捷键
    xml文件头文件生成策略以及导入约束条件
    HTTP协议状态代码和错误状态含义的解释
    水了一个前端面试 记下问的东西
    整理的一些PHP面试题目
    Magic Index 寻找数组中A[i]=i的位置(原题转自微信号待字闺中)
    【经典算法】寻找最长01字串(转自待字闺中)
    PHP中不用第三个变量交换两个变量的值
    已知一个数组a[N]来构造数组b[N]的有趣算法题
    MySQL安装后默认自带数据库的作用
  • 原文地址:https://www.cnblogs.com/Idi0t-N3/p/14686717.html
Copyright © 2011-2022 走看看