ZOJ-3790

41 篇文章 0 订阅

本来以为是DP,后来发现是模拟。。思路如下,先按种类存入map,每个颜色记录连续段的长度和末位置,存入列表,然后针对每种颜色寻找remove最多K个格后的最大连续段,注意是最多remove K个,而不是精确K个,用一个队列来搞,记录当前状态最多可移除的量,不断push队列尾连续段,如果可移除量不够了,就pop队首,这样可移除量就增加了,中间不断更新最大连续段

#include<cstdio>
#include<deque>
#include<map>
#include<vector>
#include<algorithm>

using namespace std;

namespace
{
	deque<pair<int, int> > Q;

	int solve(const vector<pair<int, int> > &v, const int K)
	{
		int res = 0, now = K;
		Q.clear();
		Q.push_back(v.front());
		int len = v.front().first;
		res = max(res, len);
		for (size_t i = 1; i < v.size(); i++)
		{
			now -= v[i].second - v[i].first - Q.back().second;
			Q.push_back(v[i]);
			len += v[i].first;
			while (now < 0)
			{
				pair<int, int> p = Q.front();
				Q.pop_front();
				now += Q.front().second - Q.front().first - p.second;
				len -= p.first;
			}
			res = max(res, len);
		}
		return res;
	}

	void put(map<int, vector<pair<int, int> > > &M, int key, int count, int end)
	{
		if (M.find(key) != M.end())
			M[key].push_back(make_pair(count, end));
		else
		{
			vector<pair<int, int> > v;
			v.push_back(make_pair(count, end));
			M[key] = v;
		}
	}
}

int main()
{
	int N, K, C;
	map<int, vector<pair<int, int> > > M;
	while (scanf("%d %d", &N, &K) != EOF)
	{
		M.clear();
		int prev = 0, count = 0;
		for (int i = 0; i < N; i++)
		{
			scanf("%d", &C);
			if (!prev)
				count = 1;
			else if (C == prev)
				count++;
			else
			{
				put(M, prev, count, i - 1);
				count = 1;
			}
			prev = C;
		}
		put(M, prev, count, N - 1);
		int res = 0;
		for (map<int, vector<pair<int, int> > >::iterator it = M.begin();
				it != M.end(); it++)
			res = max(res, solve((*it).second, K));
		printf("%d\n", res);
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值