POJ - 3700 Missile Defence System dfs + 贪心 做法

7 篇文章 0 订阅

题目描述

给定一个序列, 求可以用多少个严格上升或者严格下降的子序列包含完这整个序列

样例

Sample Input
5
3 5 2 4 1
0 
Sample Output
2

思路

  • 以寻找递增子序列为例, 我们遍历每个元素, 寻找之前的递增子序列中, 有没有大于它的, 有就将它放在全面的那个序列的后面, 没有就再开一个序列, 即是总序列数加一, 递减子序列一样的操作。
  • 对于每个数, 我们都去尝试放入递增和递减这两种情况,搜索最后的答案
#include <iostream>
#include <cstring>
#include <sstream>

using namespace std;
const int N = 1010;

string s;
int a[N], Up[N], Down[N];
int n;
int ans;

void dfs(int u, int upNum, int downNum)
{
    if(upNum + downNum >= ans)  //剪枝
	    return; 
	if(u > n)
	{
		if(upNum + downNum < ans)
			ans = upNum + downNum;
		return ;
	}
	
	
	int k = 1;  // 寻找递增的子序列
	while(k <= upNum && a[u] <= Up[k]) k++;
	int t = Up[k];
	Up[k] = a[u];
	if(k > upNum)
		dfs(u + 1, upNum + 1, downNum);
	else dfs(u + 1, upNum, downNum);
	Up[k] = t;
	
	k = 1; //寻找递减的子序列
	while(k <= downNum && a[u] >= Down[k]) k++;
	t = Down[k];
	Down[k] = a[u];
	if(k > downNum)
		dfs(u + 1, upNum, downNum + 1);
	else dfs(u + 1, upNum, downNum);
	Down[k] = t;
}

int main()
{
    while(cin >> n, n)
    {
    	for(int i = 1; i <= n; i++)
    		cin >> a[i];
    	
    	ans = n;
    	dfs(1, 0, 0);
    	cout << ans <<endl;
	}
    
    
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值