题意:
就是给定一行行的座位,安排士兵去坐,总共有K组士兵,每组士兵有ai个,要求就是不是同一组的士兵不能相邻,问能否安排好这些士兵?
座位的结构就是:
分析:
这题一看就是贪心,思路就是对于一组士兵,人数为a,如果a人数超过4个,那不断往中间位置放4个人直至中间位置不够或者人数少于4个。
然后再把剩下的人不断放两个人放到两边的位置上直到人数不够或者位置不够,将最后剩下的2个和1个的人记录下来。
之后如果两边的位置有剩余,那就先将剩下的1个人放到一个位置上,然后再来往中间位置上放人,这里就是坑点所在:
放中间的搭配可以是1 + 2, 1 + 1, 2,三种,但是最佳的策略是是1和2的人数差距尽量小,那就可以坐得更密,因此,可以将2个人拆成1 + 1,这是这道题的关键所在:
样例:
2 7
2 2 2 2 2 2 2
就是这种情况,注意到这个就可以解决这道题了。。。
AC代码:
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
int main()
{
int n, k;
scanf("%d%d", &n, &k);
int rtwo = 2 * n, rfour = n;
int one = 0, two = 0;
int x;
int tmp = 0;
while(k--)
{
scanf("%d", &x);
tmp = min(x / 4, rfour);
x -= 4 * tmp;
rfour -= tmp;
if(x == 3 && rfour > 0)
{
rfour -= 1;
x = 0;
continue;
}
tmp = min(x / 2, rtwo);
x -= 2 * tmp;
rtwo -= tmp;
two += (x / 2);
one += (x % 2);
}
tmp = min(rtwo, one);
rtwo -= tmp;
one -= tmp;
while(one < two)
{
two -= 1;
one += 2;
}
tmp = min(one, two);
one -= tmp;
two -= tmp;
tmp = tmp + (one / 2) + (one % 2) + two;
if(tmp <= rfour)
printf("YES\n");
else printf("NO\n");
return 0;
}