CF839 B 贪心

很玄的一道贪心题,大意是给出k排 XX - XXXX - XX这样的座位,有n个团体,要求不同团体不能相邻而坐,中间可以空一个座位或是由走廊隔开。

很明显最先想到可以以2为单位划分座位,但是中间4连座可以只坐2~3人,所以记录2连座个数(包括4连座,因为必要时可以转换成两个2连座),4连座个数。标记下不同团体人数的出现个数,因此对于一个团体先以4划分,剩下的部分如果是3,那么继续以2划分,如果剩下1,那么找是否有2连座,填入即可。具体要不断增加人数改变后的个数,和座位个数的变化。

/** @Date    : 2017-08-12 23:42:09
  * @FileName: B.cpp
  * @Platform: Windows
  * @Author  : Lweleth (SoungEarlf@gmail.com)
  * @Link    : https://github.com/
  * @Version : $Id$
  */
#include <bits/stdc++.h>
#define LL long long
#define PII pair<int ,int>
#define MP(x, y) make_pair((x),(y))
#define fi first
#define se second
#define PB(x) push_back((x))
#define MMG(x) memset((x), -1,sizeof(x))
#define MMF(x) memset((x),0,sizeof(x))
#define MMI(x) memset((x), INF, sizeof(x))
using namespace std;

const int INF = 0x3f3f3f3f;
const int N = 1e5+20;
const double eps = 1e-8;


int a[N];
int cnt[5];
int main() {
	int n, k;
	while(cin >> k >> n) {
		MMF(cnt);
		MMF(a);
		cnt[4] = k, cnt[2] = 2 * k;
		int x;
		for(int i = 0; i < n; i++) 
			scanf("%d", &x), a[x]++;
		int flag = 0;
		for(int i = N; i >= 1 && !flag; i--) {
			while(a[i]--) {
				flag = 1;
				for(int j = 4; j >= 1; j--) {
					if(cnt[j]) {
						a[i - min(i, j)]++;
						if(j - min(i, j) - 1 >= 0)
							cnt[j - min(i, j) - 1]++;
						flag = 0;
						cnt[j]--;
						break;
					}
				}
				if(flag)
					break;
				//cout << i << "~" << a[i] << endl;
			}`
		}
		printf("%s
", flag?"NO":"YES");

	}
    return 0;
}
原文地址:https://www.cnblogs.com/Yumesenya/p/7449823.html