codeforces D. Domino for Young(二分匹配-黑白染色)详解

Codeforces Round #609 (Div. 2) D. Domino for Young
time limit per test
3 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

You are given a Young diagram.

Given diagram is a histogram with nn columns of lengths a1,a2,,ana1,a2,…,an (a1a2an1a1≥a2≥…≥an≥1).

Young diagram for a=[3,2,2,2,1]a=[3,2,2,2,1].

Your goal is to find the largest number of non-overlapping dominos that you can draw inside of this histogram, a domino is a 1×21×2 or 2×12×1rectangle.

Input

The first line of input contain one integer nn (1n3000001≤n≤300000): the number of columns in the given histogram.

The next line of input contains nn integers a1,a2,,ana1,a2,…,an (1ai300000,aiai+11≤ai≤300000,ai≥ai+1): the lengths of columns.

Output

Output one integer: the largest number of non-overlapping dominos that you can draw inside of the given Young diagram.

Example
input
5
3 2 2 2 1

  

output
4

  

Note

Some of the possible solutions for the example:

题意:给你一个像上面的young图,前一列的高度大于等于后一列的高度,问能放下多少个1X2,或者2X1的矩阵?

分析这可以看出二分匹配,因为相邻的两个点要匹配成一个矩阵,那么我们建图?就有3*10的5次方*3*10的5次方*2条边(没分析错的话),匈牙利匹配是O(n*m)。不用想了,不可能。

那么怎么能模拟出正确的答案呢?我们用黑白染色法,直接黑白相间染色,取出颜色染的最少的就是匹配好的矩阵了。详情请看注释:

#include<bits/stdc++.h>
using namespace std;
#define ll long long int
ll a[300005];
ll c[2];
int main(void)
{
	int n;
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		scanf("%lld",&a[i]);
		//从左到右,每一列先上面开始染色
		//先染白色 
		c[0]+=a[i]/2;//白色 
		//然后染黑色 
		c[1]+=a[i]/2;//黑色
		 
		if(a[i]%2==1)//此列基数个,必然有一个颜色多染一个点 
		//多的这个点只考虑这列染什么颜色都行 
		c[i%2]++;//就规定奇数列染白色,偶数列染黑色
		//是因为假如上一行有一个没染色,这一行也有一个没染色
		//为了能让更多的相邻的黑白点匹配,那么只有让前一列和后一列染不同的颜色了 
		//printf("0:%d 1:%d\n",c[0],c[1]); 
	}
	ll count=min(c[0],c[1]);
	printf("%lld\n",count);
	return 0;
}

  部分参考于:https://www.cnblogs.com/YDDDD/p/12082619.html

猜你喜欢

转载自www.cnblogs.com/xuanmaiboy/p/12112017.html