【HAOI 2007】 上升序列

本文介绍了一种解决特定算法问题的方法,该问题要求预处理一个整数序列,通过将其反转并找到最长下降子序列来解答后续的询问。文章详细展示了如何使用C++实现这一算法,并通过实例代码解释了其工作原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

【题目链接】

          点击打开链接

【算法】

          先预处理 : 将序列反转,求最长下降子序列

          对于每个询问,根据字典序性质,贪心即可

【代码】

         

#include<bits/stdc++.h>
using namespace std;
#define MAXN 10010

int i,j,len,n,q,mx,pre,l;
int a[MAXN],f[MAXN];
vector<int> res;

template <typename T> inline void read(T &x)  
{  
    int f = 1; x = 0;  
    char c = getchar();  
    for (; !isdigit(c); c = getchar()) { if (c == '-') f = -f; }  
    for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - '0';  
    x *= f;   
}  
template <typename T> inline void write(T x)  
{  
    if (x < 0)   
    {  
        putchar('-');  
        x = -x;   
    }     
    if (x > 9) write(x/10);  
    putchar(x%10+'0');  
}  
template <typename T> inline void writeln(T x)  
{  
    write(x);  
    puts("");  
}  

int main() {
		
		read(n); 
		for (i = 1; i <= n; i++) read(a[i]);
		reverse(a+1,a+n+1);
		for (i = 1; i <= n; i++)
		{
				f[i] = 1;
				for (j = i - 1; j >= 1; j--)
				{
						if (a[i] < a[j])
								f[i] = max(f[i],f[j]+1);
				}
				mx = max(mx,f[i]);
		}
		
		read(q);
		while (q--)
		{
				read(l);
				if (l > mx) 
				{
						puts("Impossible");
						continue;
				} else
				{
						res.clear();
						pre = 0;
						for (i = n; i >= 1; i--)
						{
								if (f[i] >= l && a[i] > pre)
								{
										res.push_back(a[i]);
										l--;
										pre = a[i];	
								}		
								if (!l) break;
						} 
						len = res.size();
						for (i = 0; i < len - 1; i++) 
						{
								write(res[i]);
								putchar(' ');
						}
						writeln(res[len-1]);
				} 
		}
		return 0;
	
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值