hust校赛 f题 The tree of hust(lis 变形)

题目大意是给出一段数字序列,可以忽略一次一段连续的序列,求忽略后的最长连续上升子序列

思路是dp,用end数组记录以当前元素作为结尾的最长连续上升序列的元素个数,那么不难得到状态转移方程为

dp(i) = max(dp(i - 1),  max( end[k] ) ) + 1

代码如下:

#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<vector>
#include<map>
#include<queue>
#include<stack>
#include<string>
#include<map>
#include<set>
#include<ctime>
using namespace std;
#define LL long long
const int maxn = 200009;
const int INF = 1000000007;

int a[maxn], enda[maxn], d[maxn], g[maxn]; //enda数组记录以当前元素结尾的最长上升连续序列的长度 

int main() {
	int startt = clock();
	freopen("input.txt", "r", stdin);
	int t, kase = 0;
	scanf("%d", &t);
	while(t--) {
		int n; scanf("%d", &n);
		a[0] = 0; enda[0] = 0;
		for(int i = 1; i <= n; i++) {
			scanf("%d", &a[i]);
			if(a[i] > a[i - 1]) enda[i] = enda[i - 1] + 1;
			else enda[i] = 1;
		//	printf("%d\n", enda[i]);
		}

		int ans = 0;
		for(int i = 1; i <= n; i++) g[i] = INF;  //lis的变形,g[i]表示enda的值为i的最小元素值
		for(int i = 1; i <= n; i++) {
			int k = lower_bound(g + 1, g + n + 1, a[i]) - g - 1;

			if(a[i] > a[i - 1])	d[i] = max(d[i - 1], k) + 1;
			else d[i] = k + 1;

			ans = max(ans, d[i]);
			g[enda[i]] = min(g[enda[i]], a[i]);
		//	printf("%d\n", d[i]);
		} 

		printf("Case #%d: %d\n", ++kase, ans);
	}
	int endt = clock();
	printf("%d\n", endt - startt);
	return 0;
}
时间: 2024-10-19 14:29:33

hust校赛 f题 The tree of hust(lis 变形)的相关文章

2015 whu校赛f题big data(dp + 小技巧)

题意是给定五个数n(n <= 100),a,b,l,r 另外有函数序列f(x),其中f(x + 1) = f(x) + a或f(x)+ b,f(0) = 0,问有多少个这样的函数序列f(1)到f(n)使得函数序列的和在l和r之间 解题思路如下: 图片有一处错误,要减去的是a*(n + 1) * n而不是 (b - a)* (n + 1) * n,此外,要注意x/c时向上取整和向下取整的问题. 这道题做做停停一个月了今天终于找时间ac了,有点感人呐 代码如下: #include<cstdio&g

hust校赛d题 PHP is the best language int the world(二分图着色+递推)

题目大意是给出一个图,要求判断是否是二分图,如果是,求二分图两个节点集之差的最小值. 两个人如果不会争吵的话连一条边,形成一个图,取这个图的反图.这个反图之间存在边则 说明这两个人不能在同一个team.首先二分染色看是否能够将反图变成一个二分图. 如果能染成二分图,记录每个二分图颜色人数.在某个联通分量里白色/黑色可以交换. 接下来用dp[i][j] = 1表示前i个联通分量能够形成一个人数为j的team. 然后在dp[num][s]里面遍历找到相差最小的team分法,输出答案,num为联通分量

hust校赛c题 Move the Books(“最重上升子序列”)

题意是:给定一组整数,通过移动使这个序列变为递增的,移动i元素的话费为i 例如 2 2 5 3 4通过移动5使得序列变为2 2 3 4 5故最小花费为5,如果移动3 4那么花费会为7 这道题可以通过求"最重上升子序列"来间接地得到结果, dp[i]表示以weight[i] 为终点递增的最重的一系列书的重量之和.状态转移方程是 dp[i] = max(dp[i], dp[k] + weight[i]) (1 <= k <= i && weight[i] >

CSU 1425 NUDT校赛 I题 Prime Summation

这个题本来有希望在比赛里面出了的 当时也想着用递推 因为后面的数明显是由前面的推过来的 但是在计算的时候 因为判重的问题 ...很无语.我打算用一个tot[i]来存i的总种树,tot[i]+=tot[j]//j为可以由j推到i的一系列数,但这样是不对的,会产生大量重复计算... 看了下标程才发现要用二维来计算出种类总数,f[i][j]+=sum(f[i-j][k]) 表示在推i数的时候,第一个素数为j的种类数,注意j一定为素数,而且k不能大于j...标程里面处理的比较简练,就学了下他的写法. 至

北邮校赛 F. Gabriel&#39;s Pocket Money(树状数组)

F. Gabriel's Pocket Money 2017- BUPT Collegiate Programming Contest - sync 时间限制 2000 ms 内存限制 65536 KB 题目描述 For centuries, Heaven has required its young angels to live and study among humans in order to become full-fledged angels. This is no different

PKU2018校赛 H题 Safe Upper Bound

http://poj.openjudge.cn/practice/C18H 题目 算平均数用到公式\[\bar{x}=\frac{x_1+x_2+x_3+\cdots+x_n}{n}\] 但如果用int型计算,那么\(x_1+x_2+x_3+\cdots+x_n\)可能会超过\(2^{31}-1\) 算6个数的平均数可以这么算 Calculate the average of\(x_1,x_2,x_3\)\[\bar{x}_1=\frac{x_1+x_2+x_3}{3}\]Calculate t

HDU 5002 Tree (2014年鞍山赛区网络赛F题)

1.题目描述:点击打开链接 2.解题思路:LCT的模板题 3.代码: #include <cstdio> #include <cstdlib> #include <algorithm> #include <iostream> #include <vector> using namespace std; const int N = 111111; const int INF = 1111111111; int n, m; class LCT { p

(中等) Hiho 1232 Couple Trees(15年北京网络赛F题),主席树+树链剖分。

"Couple Trees" are two trees, a husband tree and a wife tree. They are named because they look like a couple leaning on each other. They share a same root, and their branches are intertwined. In China, many lovers go to the couple trees. Under t

哈理工校赛F题 递归分治

比赛时不会,在小岛的帮助下还是把这道题做出来了 F.粉刷栅栏 Description 给定一组长度为 n 的栅栏,从左到右高度依次是 h[i]. 你需要对这个栅栏粉刷油漆,每次你可以粉刷一行或者一列. 问最少粉刷几次,可以给所有栅栏上漆.(不能多刷) Input 第一行包含一个整数,表示栅栏的长度. 接下来的一行,包含 n 个数(n <= 5000),依次表示 h[i](0 <= h[i]<= 10). Output 输出一行表示对应的答案.. Sample Input 1 5 2 2