P1114 “非常男女”计划(相对差,前缀和,剪枝)

如果有一段区间 

特殊点:需要特判

k1==k2  男女数相同,他们的l[t]一定是0,r[t]可以变化

所以只有k1=k2  t!=n   l数组才可以存下标,不然会出错

所以需要增加一个特判  t!=n

特殊情况:需要特别处理

由于男生数k1,女生数k2,t=k1-k2可能会小于0,会导致下标越界

那么我们让t+=n,变成t=k1-k2+n  下标就不会越界了

注意  要么不加,然后所有涉及到t的地方都写成t+n

        要么直接加上  比较方便

相对差 

#include <iostream>
#include <algorithm>
#include <unordered_map> 
using namespace std;
const int N = 1E6 + 5;
int l[2*N], r[2*N];		//l表示第一个出现某个下标的位置,r表示最后一个出现某个下标的位置
int a[N];
int main()
{
	int n;
	cin >> n;
	int k1 = 0,k2=0;	//0~某点  相对差
	for (int i = 1;i <= n;i++)
	{
		cin >> a[i];
		if (a[i]) k1 += 1;
		else k2 += 1;
		//这里可能k会小于0,+n优化
		int t = k2 - k1 + n;
		if (!l[t]&&t!=n) l[t] = i;
		//t!=n 一定要加   如果k2==k1 说明0~这一点男女数相同
		else r[t] = i;
	}
	int res = 0;
	for (int i = 1;i <=2*n;i++)
	{
		res = max(res, r[i] - l[i]);
	}
	
	cout << res;
}

前缀和剪枝 

这题用前缀和来做的话会发现一个性质

1.一个区间的和如果==区间长度/2  那么这个区间必然是男女生能够全部匹配的

但是这样子做的时间复杂度是O(N^2)  ,我们通过暴力剪枝,如果枚举的区间长度<res,就不枚举了

可以有效地降低时间复杂度

#include <iostream>
#include <algorithm>
using namespace std;

const int N = 100005;
int a[N];
int s[N];
int main()
{//前缀和 O(n^2)会超时
//和dfs剪枝类似,采用
	int n;
	cin >> n;
	for (int i = 1;i <= n;i++)
	{
		cin >> a[i];
		s[i] = s[i - 1] + a[i];
	}
	int ans = 0;
	for (int i = 1;i <= n;i++)
	{
		for(int j = n;j >= i;j--)
		{
			if (j - i + 1 < ans)
				break;
			if ((s[j] - s[i - 1]) * 2 == j - i + 1)
				ans = max(j-i+1, ans);
		}
	}
	cout << ans;
	
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值