让我头疼的手套问题

题目描述:
在地下室里放着n种颜色的手套,手套分左右手,但是每种颜色的左右手手套个数不一定相同。A先生现在要出门,所以他要去地下室选手套。但是昏暗的灯光让他无法分辨手套的颜色,只能分辨出左右手。所以他会多拿一些手套,然后选出一双颜色相同的左右手手套。现在的问题是,他至少要拿多少只手套(左手加右手),才能保证一定能选出一双颜色相同的手套。

给定颜色种数n(1≤n≤13),同时给定两个长度为n的数组left,right,分别代表每种颜色左右手手套的数量。数据保证左右的手套总数均不超过26,且一定存在至少一种合法方案。

测试样例:

4,[0,7,1,6],[1,5,0,6]
返回:10(解释:可以左手手套取2只,右手手套取8只)

简单分析:这道题我实在是想不透,不过看别人的大体思想还是写出了程序。
要找最少的手套个数,要分两种情况:
1、在左右手套每种颜色都不为0时,我们只需把左手手套每种颜色全部取到(左手手套总数-左手最小手套数+1),再取一个右手手套就一定可以匹配;然后把右手手套每种颜色全部取到(右手手套总数-右手最小手套数+1),再取一个左手手套就一定可以匹配,然后取两者最小值。
2、在左右手手套有某种颜色手套数量为0时,我们需要做如下考虑:
【0 7 1 6】 【1 5 0 6】,我们可以很容易看到。在把左右手为0的颜色排除考虑时,右手取7只就能把剩下的所以颜色取到,左手取1只就行。但是如果把为0的考虑进去,左手可能取第3种颜色进而无法匹配,所以左手要取1+1只手套;右手取7只手套可能正好把颜色1和4取到,没有达到取区别颜色的目的,所以需要额外多取几个以保证颜色1的手套不会影响我们取到全部颜色。
代码:

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int findMinimum(int n, vector<int> left, vector<int> right)
{
	// write code here
	int left_min = INT_MAX, left_sum = 0;
	int right_min = INT_MAX, right_sum = 0;
	int sum = 0;
	for (int i = 0; i < n; ++i)
	{
		if (left[i] * right[i] == 0)
			sum += left[i] + right[i];
		else
		{
			left_sum += left[i];
			left_min = min(left_min, left[i]);
			right_sum += right[i];
			right_min = min(right_min, right[i]);
		}
	}
	return sum + min(left_sum - left_min + 1, right_sum - right_min + 1) + 1;
}

int main()
{
	vector<int> left = { 10, 9, 8, 7 };
	vector<int> right = { 4, 3, 2, 1 };
	int ret = findMinimum(4, left, right);
	cout << ret << endl;
	return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值