zoukankan      html  css  js  c++  java
  • 21.09.10模拟 雷神领域

    题意就是让你找成直角三角形三个顶点位置的信标,然后直角三角形外接矩形的另外一个空点也会出现信标,最后求一条0,0,到n,n的路径,使得路径上信标最多(显然简单的DP)
    关键是怎么处理出新的信标,显然我们有个n^2的写法,但是这样太慢了,我们就换个思路,在DP时,怎么判断当前点有没有信标?不处理出来 。
    坐标离散化后每个点看成连x,y坐标的结点的边,每个联通二分图里面的左右能互达的一对点所形成的坐标系上的点都是信标
    我们可以对x,y坐标建立集合,就是用并查集维护这个集合, 某个位置信标存在,即该点x,y是在同一个集合。

    #include<iostream>
    #include<bitset>
    #include<cstdio>
    #define rep(i,j,k) for(register int i(j);i<=k;++i)
    #define drp(i,j,k) for(register int i(j);i>=k;--i)
    #define bug cout<<"~~~~~~~~~~~~~"<<'
    ';
    #define bugout(x) cout<<x<<endl;
    using namespace std;
    typedef long long lxl;
    template<typename T>
    inline T  max(T &a, T &b) {
    	return a > b ? a : b;
    }
    template<typename T>
    inline T  min(T &a, T &b) {
    	return a < b ? a : b;
    }
    
    inline char gt() {
    	static char buf[1 << 21], *p1 = buf, *p2 = buf;
    	return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++;
    }
    template <typename T>
    inline void  read(T &x) {
    	register char ch = gt();
    	x = 0;
    	int w(0);
    	while(!(ch >= '0' && ch <= '9'))w |= ch == '-', ch = gt();
    	while(ch >= '0' && ch <= '9')x = x * 10 + (ch & 15), ch = gt();
    	w ? x = ~(x - 1) : x;
    }
    template <typename T>
    inline void out(T x, char cc) {
    	if(x < 0) x = -x, putchar('-');
    	char ch[20];
    	int num(0);
    	while(x || !num) ch[++num] = x % 10 + '0', x /= 10;
    	while(num) putchar(ch[num--]);
    	putchar(cc);
    }
    
    const int N = 15700;
    const int MX = 5e3 + 7;
    int f[MX][MX];
    int  n;
    
    int fa[N * 2];
    inline int find(int x) {
    	while(x != fa[x]) x = fa[x] = fa[fa[x]];
    	return x;
    }
    
    inline void merge(int x, int y) {
    	x = find(x);
    	y = find(y);
    	if(x == y) return;
    	fa[x] = y;
    }
    
    int main() {
    	freopen("field.in", "r", stdin);
    	freopen("field.out", "w", stdout);
    	read(n);
    
    	rep(i, 1, 2 * MX) {
    		fa[i] = i;
    	}
    
    	int x, y, a, b;
    	rep(i, 1, n) {
    		read(x);
    		read(y);
    		merge(x, y + 5000);
    	}
    	rep(i, 1, 5000) {
    		rep(j, 1, 5000) {
    			x = find(i);
    			y = find(j + 5000);
    			f[i][j] = max(f[i - 1][j], f[i][j - 1]);
    			if(x == y) f[i][j]++;
    		}
    	}
    	out(f[5000][5000], '
    ');
    	return 0;
    }
    

    本文来自博客园,作者:{2519},转载请注明原文链接:https://www.cnblogs.com/QQ2519/p/15375463.html

  • 相关阅读:
    [Luogu]小Z的AK计划
    [POI2006]OKR-Periods of Words
    [NOI2014]动物园
    [NOI2009]管道取珠
    [IOI2005]河流
    [国家集训队]Crash的文明世界
    [HDU5382]GCD?LCM!
    [AGC027E]ABBreviate
    [CF]Round510
    [NOIp2005]篝火晚会
  • 原文地址:https://www.cnblogs.com/QQ2519/p/15375463.html
Copyright © 2011-2022 走看看