BZOJ 1046 HAOI 2007 上升序列 DP

题目大意:给出一个序列,求出字典序最小的长度为k的上升序列。

思路:先随便搞搞求出一个数组f,表示从i开始最长的上升序列的长度。然后贪心的往后找,能放在当前位置就放。

CODE:

#define _CRT_SECURE_NO_WARNINGS

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define MAX 10010
#define INF 0x3f3f3f3f
using namespace std;

int src[MAX];
int f[MAX],max_length[MAX];
int cnt,asks;

bool cmp(int a,int b)
{
	return src[a] > src[b];
}

int ans[MAX];

int main()
{
	cin >> cnt;
	for(int i = 1; i <= cnt; ++i)
		scanf("%d",&src[i]);
	for(int i = cnt; i; --i) {
		int p = lower_bound(f + 1,f + cnt + 1,i,cmp) - f;
		max_length[i] = max_length[f[p - 1]] + 1;
		f[p] = i;
	}
	int length = 0;
	while(f[length + 1])	++length;
	cin >> asks;
	for(int x,i = 1; i <= asks; ++i) {
		scanf("%d",&x);
		if(x > length)	puts("Impossible");
		else {
			int temp = x,last = -INF;
			for(int i = 1; i <= cnt; ++i)
				if(max_length[i] >= temp && src[i] > last) {
					printf("%d",src[i]);
					last = src[i];
					--temp;
					if(temp)	putchar(' ');
					else {
						puts("");
						break;
					}
				}
		}
	}
	return 0;
}

时间: 2024-08-09 14:48:47

BZOJ 1046 HAOI 2007 上升序列 DP的相关文章

[BZOJ 1046][HAOI 2007]上升序列(nlogn的LIS算法)

题目链接:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1046 有人说这题是NOIP难度?表示怀疑,蒟蒻认为此题难度略大于NOIP.... 这个题的序列长度n<=1e4,如果用n^2的LIS做法肯定TLE,只能用nlogn的算法,这种算法在http://www.slyar.com/blog/longest-ordered-subsequence.html中有详细讲解. 由于题目题意要求,我们需要求出以每个数字开头的最长上升子序列长度,但

【BZOJ 1046】 [HAOI2007]上升序列

1046: [HAOI2007]上升序列 Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 2688  Solved: 891 [Submit][Status] Description 对于一个给定的S={a1,a2,a3,-,an},若有P={ax1,ax2,ax3,-,axm},满足(x1 < x2 < - < xm)且( ax1 < ax2 < - < axm).那么就称P为S的一个上升序列.如果有多个P满足条件,那

HAOI 2007 上升序列

对于一个给定的S={a1,a2,a3,…,an},若有P={ax1,ax2,ax3,…,axm},满足(x1<x2<…<xm)且(ax1<ax2<…<axm).那么就称P为S的一个上升序列.如果有多个P满足条件,那么我们想求字典序最小的那个. 任务 给出S序列,给出若干询问.对于第i个询问,求出长度为Li的上升序列,如有多个,求出字典序最小的那个(即首先x1最小,如果不唯一,再看x2最小……),如果不存在长度为Li的上升序列,则打印Impossible. 输入 第一行一

BZOJ 1057 ZJOI 2007 棋盘制作 DP+悬线法

题目大意:给出一个由01形成的矩阵,问这个矩阵中最大面积的正方形和矩形,其中任意一个方块相邻的都是不同的格子. 思路:其实吧所有(i + j)&1的位置上的数字异或一下,就变成都是0或者都是1的最大正方形和矩形了.第一问就是水DP,第二问可以单调栈或者悬线.都很好写. CODE: #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define

[BZOJ 1053] [HAOI 2007]反素数ant

1053: [HAOI2007]反素数ant Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1857  Solved: 1034[Submit][Status][Discuss] Description 对于任何正整数x,其约数的个数记作g(x).例如g(1)=1.g(6)=4.如果某个正整数x满足:g(x)>g(i) 0<i<x,则称x为反质数.例如,整数1,2,4,6等都是反质数.现在给定一个数N,你能求出不超过N的最大的反质数么?

[BZOJ 1047][HAOI 2007]理想的正方形(二维滑动窗口+单调队列)

题目链接:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1047 思路:裸的二维上的滑动窗口问题,可以借鉴一维滑动窗口的思路.首先预处理出每一列j的.以第i行元素为结尾.长度为n的区间的最大值maxv[i][j].最小值minv[i][j],然后再搞每一行,求出以每一行i结尾.行标上长度为n的区间.以第j列结尾.列标上长度为n的区间得到的二维区间最大值与最小值之差,遍历每一行得到这个差的最小值即为答案. #include <iostrea

BZOJ 1047 HAOI 2007 理想的正方形 单调队列

题目大意:给出一个矩阵,求出一个k*k的子矩阵,使得这个矩阵中最大值和最小值的差最小,输出这个差值. 思路:利用单调队列维护每一行的数字,求出一个数字前面k个数字中的最大值和最小值,然后在列上暴力求出真个矩阵的最大值和最小值,总时间复杂度O(M*M+M*M*K). CODE: #include <queue> #include <cstdio> #include <cstring> #include <iostream> #include <algor

[BZOJ 1046] [HAOI2007] 上升序列 【DP】

题目链接:BZOJ - 1046 题目分析 先倒着做最长下降子序列,求出 f[i],即以 i 为起点向后的最长上升子序列长度. 注意题目要求的是 xi 的字典序最小,不是数值! 如果输入的 l 大于最长上升子序列长度,输出 Impossible. 否则,从 1 向 n 枚举,贪心,如果 f[i] >= l,就选取 a[i],同时 --l,然后继续向后找比 a[i] 大的第一个数判断是否 f[i] >= l (这时l已经减小了1). 代码 #include <iostream> #i

【学习】序列DP

做了也有一段时间的序列DP了,发现了一些规律 如果有两个字符串,一般来说,f[i][j]表示S串到第i位,T串到第j位. 如果lenS==lenT,可能可以优化到1维. 如果只有1个序列的话,一般来说f[i]表示到第i位的状态. 有一些特殊的东西:最长回文子序列是把原串倒过来然后做一遍最长公共子序列,检查一下奇偶性×2即可. 然后呢还有最长回文子串有个manacher算法来着改天要去看看. BZOJ上的题好像只做了一道呀= =好像是带计数的数列DP呀,用容斥原理搞一下就好咯. 感觉自己还是很弱还