1. 程式人生 > >CF839 B 貪心

CF839 B 貪心

mail pac make git 標記 printf () lena long

很玄的一道貪心題,大意是給出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 ([email protected])
  * @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\n", flag?"NO":"YES");

	}
    return 0;
}

CF839 B 貪心