• HGOI 20200716


    海星,一天比一天简单
    开题顺序2-3-1,跟ZJOI一样

    T1 交错匹配(cross)

    这个题稍微复杂些

    首先看到图片容易想到二分图匹配,但由于题目中的交叉限制,是不大可能(?)用匈牙利或网络流做的

    在仔细观察这个题就是最大字串匹配加了一个限制,数据也是给 (O(N^2)) 出的

    考虑如何把这个信息处理掉

    由于每个左斜匹配只会与一个右斜匹配对应,

    为了最大化答案,每个 (a) 应当和更接近的 (b) 匹配, 每个 (b) 应当和更接近的 (a) 匹配

    这样的话我们就可以模仿最大字串的做法

    (f[i][j]) 表示 (a) 串匹配到第 (i) 位,(b) 串匹配到第 (j) 位 的最大匹配数量

    枚举 (a) 串的每个元素 (i),记录每个数出现的最前位置

    然后枚举 (b) 串的每个元素 (j)

    由于 (i) 以后的元素还未经处理,因此只会出现

    i'     i 
    * .. . x ..
    j'   j
    x .. *
    

    这样的情况

    因此我们就只需要记录下 (b)数组中与 (a[i]) 相等的最靠近 (i) 的元素编号即可 (代码中为 (lst)

    转移方程:
    (f[i][j] = max(f[i][j], f[s[b[j]] - 1][lst - 1] + 2))

    (f[i][j]) 的初始值是 (max(f[i - 1][j], f[i][j - 1]))

    答案 (f[n][m])

    如果没有那个 (1 v 1) 的限制应该怎么做啊。

    数组开小太搞笑

    #include <bits/stdc++.h>
    using namespace std;
    
    #define rep(i, a, b) for (int i = a; i <= b; i++)
    #define per(i, a, b) for (int i = a; i >= b; i--)
    #define siz(a) (int)a.size()
    #define pb push_back
    #define mp make_pair
    #define ll long long
    #define fi first
    #define se second
    
    const int N = 1010 ;
    
    int n, m, lst ;
    int a[N], b[N], s[N] ;
    int f[N][N] ; // f[i][j] 表示a串匹配到第i位,b串匹配到第j位 
    
    signed main() {
    	freopen("cross.in", "r", stdin) ;
    	freopen("cross.out", "w", stdout) ;
    	scanf("%d%d", &n, &m) ;
    	rep(i, 1, n) scanf("%d", &a[i]) ;
    	rep(i, 1, m) scanf("%d", &b[i]) ;
    	memset(s, 0x3f, sizeof(s)) ;
    	rep(i, 1, n) {
    		lst = 0 ;
    		rep(j, 1, m) {
    			f[i][j] = max(f[i - 1][j], f[i][j - 1]) ;
    			if (a[i] != b[j]) {
    				if (lst && s[b[j]] < i) f[i][j] = max(f[i][j], f[s[b[j]] - 1][lst - 1] + 2) ;
    			} else {
    				lst = j ;
    			}
    		}
    		s[a[i]] = i ;
    	} 
    	printf("%d
    ", f[n][m]) ;
    	return 0 ;
    }
    /*
    12 11 
    1 2 3 3 2 4 1 5 1 3 5 10
    3 1 2 3 2 4 12 1 5 5 3 
    ----
    4 4 
    1 1 3 3 
    1 1 3 3  
    */
    
    

    T2 奶牛晒衣服(dry)

    送分题

    贪心
    对于当前时间最长的衣服进行烘干即可

    #include <bits/stdc++.h>
    using namespace std;
    
    #define rep(i, a, b) for (int i = a; i <= b; i++)
    #define per(i, a, b) for (int i = a; i >= b; i--)
    #define siz(a) (int)a.size()
    #define pb push_back
    #define mp make_pair
    #define ll long long
    #define fi first
    #define se second
    
    const int N = 100010 ;
    
    int n, a, b ;
    priority_queue <int> q ;
    
    signed main() {
    	freopen("dry.in", "r", stdin) ;
    	freopen("dry.out", "w", stdout) ;
    	scanf("%d%d%d", &n, &a, &b) ;
    	rep(i, 1, n) {
    		int t ; scanf("%d", &t) ;
    		q.push(t) ;
    	}
    	int ans = 0, sum = 0 ;
    	while (!q.empty()) {
    		int x = q.top() ; q.pop() ;
    	//	cout << x << endl ;
    		if (x <= sum) {
    			printf("%d
    ", ans) ;
    			return 0 ;
    		}
    		x -= b ;
    		sum += a ;
    		ans++ ;
    		q.push(x) ;
    	}
    	printf("%d
    ", ans) ;
    	return 0 ;
    }
    /*
    3 2 1 
    1 2 3 
    */
    

    T3 奶牛排队(flip/tahort)

    对于两头奶牛 (i,j(i<j)), 如果 (a[i]<a[j]) 那么右端点选 (j) 必然比 (i) 更优

    这样的话其实 (i) 作为右端点是不可能的了

    但依然可以作为左端点

    考虑枚举左端点

    依次加入每头奶牛至队列中(栈也阔以)

    如果加入的奶牛与前一头满足上述关系就把他们合并掉

    合并的时候要考虑一下前一头奶牛能够到达的左端点能不能更新当前的信息

    然后每次对答案进行更新

    如果 (ans=1) 即只有一头奶牛那么是不合法的,(ans) 赋为 (0)

    比如(~5~4~3~2~1)

    #include <bits/stdc++.h>
    using namespace std;
    
    #define rep(i, a, b) for (int i = a; i <= b; i++)
    #define per(i, a, b) for (int i = a; i >= b; i--)
    #define siz(a) (int)a.size()
    #define pb push_back
    #define mp make_pair
    #define ll long long
    #define fi first
    #define se second
    
    const int N = 100010 ;
    
    struct range {
    	int lp, lh, rp, rh ;
    } ;
    
    range sta[N] ;
    
    int n, ans, top ;
    int a[N] ;
    
    signed main() {
    	freopen("tahort.in", "r", stdin) ;
    	freopen("tahort.out", "w", stdout) ;
    	scanf("%d", &n) ;
    	rep(i, 1, n) scanf("%d", &a[i]) ;
    	ans = 0, top = 0 ;
    	rep(i, 1, n) {
    		top++ ;
    		sta[top].lh = sta[top].rh = a[i] ;
    		sta[top].lp = sta[top].rp = i ;
    		while (sta[top].rh > sta[top - 1].rh && top > 1) {
    			if (sta[top].lh > sta[top - 1].lh) {
    				sta[top].lh = sta[top - 1].lh ;
    				sta[top].lp = sta[top - 1].lp ;
    			}
    			sta[top - 1] = sta[top] ;
    			top-- ;
    		}
    		ans = max(ans, sta[top].rp - sta[top].lp + 1) ;
    	}
    	if (ans == 1) ans = 0 ;
    	printf("%d
    ", ans) ;
    	return 0 ;
    }
    /*
    5 
    1 2 3 4 1
    */ 
    
    
  • 相关阅读:
    系统tabbar出现两个tabbar的问题解决方案。
    iOS 开发苹果由http改为https 之后,如果服务器不做相应的修改,那么客户端需要做点更改
    UIAlertController的一些简单实用方法
    ios开发同一个lab显示不同的颜色
    ios开发同一个版本多次提交不想改变版本号的解决方法
    iOS开发textfield的一些方法汇总
    C#笔记
    Shader之性能优化
    Shader之ShaderUI使用方法
    Shader Example
  • 原文地址:https://www.cnblogs.com/harryhqg/p/13323342.html
Copyright © 2020-2023  润新知