C. LuoTianyi and the Show

该文描述了一个关于VOCALOID节目的座位安排问题,人们按照特定规则坐下,规则涉及左侧、右侧和指定座位。目标是确定在任意入场顺序下能坐下的最多人数。文章提供了一种基于动态规划的解决方案,通过遍历所有可能的起始座位来计算最大值。
摘要由CSDN通过智能技术生成

here are nn people taking part in a show about VOCALOID. They will sit in the row of seats, numbered 11 to mm from left to right.

The nn people come and sit in order. Each person occupies a seat in one of three ways:

  1. Sit in the seat next to the left of the leftmost person who is already sitting, or if seat 11 is taken, then leave the show. If there is no one currently sitting, sit in seat mm.
  2. Sit in the seat next to the right of the rightmost person who is already sitting, or if seat mm is taken, then leave the show. If there is no one currently sitting, sit in seat 11.
  3. Sit in the seat numbered xixi. If this seat is taken, then leave the show.

Now you want to know what is the maximum number of people that can take a seat, if you can let people into the show in any order?

Input

Each test consists of multiple test cases. The first line contains a single integer tt (1≤t≤1041≤t≤104) — the number of test cases. The description of test cases follows.

The first line of each test case contains two integers nn and mm (1≤n,m≤1051≤n,m≤105) — the number of people and the number of seats.

The second line of each test case contains nn integers x1,x2,…,xnx1,x2,…,xn (−2≤xi≤m−2≤xi≤m, xi≠0xi≠0), the ii-th of which describes the way in which the ii-th person occupies a seat:

  1. If xi=−1xi=−1, then ii-th person takes the seat in the first way.
  2. If xi=−2xi=−2, then ii-th person takes the seat in the second way.
  3. If xi>0xi>0, then the ii-th person takes a seat in the third way, i.e. he wants to sit in the seat with the number xixi or leave the show if it is occupied..

It is guaranteed that sum of nn and the sum of mm over all test cases don't exceed 105105.

Output

For each test case output a single integer — the maximum number of people who can occupy a seat.

我们开始的时候选择一个人坐,只能选被指定的座位,或是有-1,可以从右边开始放,或是有-2,可以从左边开始放。枚举每个这种点作为先放的点, 放左边时挨着这个点放,如果是被指定的不需要消耗"-1"类的,否则填"-1"类,同理右边

#include<iostream>
#include<cstring>

using namespace std;

const int N = 1e5 + 10;

int x[N];
bool st[N];
int s[N];

int main()
{
	int t;
	cin >> t;
	while(t --)
	{
		int n, m;
		cin >> n >> m;
		memset(st, 0, sizeof st);
		memset(s, 0, sizeof s);
		int cnt1 = 0, cnt2 = 0;
		for(int i = 1; i <= n; i ++)
		{
			scanf("%d", &x[i]);
			if(x[i] == -1)
				cnt1 ++;
			else if(x[i] == -2)
			{
				cnt2 ++;
			}
			else if(!st[x[i]])
				st[x[i]] = true;
		}
		
		for(int i = 1; i <= m; i ++)
		{
			if(st[i])
			s[i] = s[i - 1] + 1;
			else
			s[i] = s[i - 1];
		}
		
		int ans = 0;
		for(int i = 1; i <= m; i ++)
		{
			if(st[i])
			ans = max(ans, 1 + min(i - 1, cnt1 + s[i - 1]) + min(m - i, cnt2 + s[m] - s[i]));
			if((cnt1 && i == m))
			ans = max(ans, 1 + min(i - 1, cnt1 - 1 + s[i - 1]) + min(m - i, cnt2 + s[m] - s[i]));
			if(cnt2 && i == 1)
			ans = max(ans, 1 + min(i - 1, cnt1 + s[i - 1]) + min(m - i, cnt2 - 1 + s[m] - s[i]));
			
		}
		cout << ans << endl;
	}
} 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值