B. Game of the Rows(贪心)

B. Game of the Rows

题目链接:http://codeforces.com/problemset/problem/839/B


大意:船上n行座位,k个小组人,每行相邻的座不能做不同组的人,给你定数据让你判定能不能放下这些人。

{ [1,2]  [3,4,5,6]  [7,8] }

{ [1,2] [3,4,5,6]  [7,8] }

.

.

.

每行的座位如上图所示的排列。

解题思路1:按照每一组单独放置,分情况(详见代码),统计长度为1,2,4的座位,那么问题来了,长度为1 的作为是怎么来的,就是长度为4 的可以分为1,2;

这里有一点,代码中每个if,elseif的位置不能变,比如,没有长度为1 的座了,但是有一个人来了,那么应该拆开长度为4 的,而不是占用一个长度为2的;虽然说都是浪费俩座

位,但是都拆开的话更灵活,以便于后面的处理,符合贪心思想(详见代码)。

#include <cstdio>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#define FIN     freopen("jogging.in","r",stdin)
#define FOUT    freopen("jogging.out","w",stdout)
using namespace std;

int main(){
    int n,k;
    int a[105];
    while(~scanf("%d%d",&n,&k))
    {
        int flag=1;

        for(int i=0;i<k;i++)
            scanf("%d",&a[i]);
        int sum4=n;
        int sum2=n*2;
        int sum1=0;
        for(int i=0;i<k;i++){
            //printf("%d %d %d\n",sum1,sum2,sum4);
            while(a[i]>0){
                if(a[i]>=4){
                    if(sum4>0){
                        sum4--;
                        a[i]-=4;
                    }
                    else if(sum2>0){
                        sum2--;
                        a[i]-=2;
                    }
                    else if(sum1>0){
                        sum1--;
                        a[i]--;
                    }
                    else{
                        flag=0;
                        break;
                    }
                }
                else if(a[i]==3){
                    if(sum4>0){
                        sum4--;
                        a[i]=0;
                    }
                    else if(sum1>0){
                        sum1--;
                        a[i]--;
                    }
                    else if(sum2>0){
                        sum2--;
                        a[i]-=2;
                    }
                    else{
                        flag=0;
                        break;
                    }
                }
                else if(a[i]==2){
                    if(sum2>0){
                        sum2--;
                        a[i]-=2;
                    }
                    else if(sum4>0)
                    {
                        sum1++;
                        sum4--;
                        a[i]-=2;
                    }
                    else if(sum1>0){
                        a[i]--;
                        sum1--;
                    }
                    else{
                        flag=0;
                        break;
                    }
                }
                else if(a[i]==1){
                    if(sum1>0){
                        sum1--;
                        a[i]--;
                    }
                    else if(sum4>0)
                    {
                        sum2++;
                        sum4--;
                        a[i]--;
                    }
                    else if(sum2>0){
                        a[i]--;
                        sum2--;
                    }
                    else{
                        flag=0;
                        break;
                    }
                }
            }
        }
        if(flag)
            printf("YES\n");
        else
            printf("NO\n");
    }

    return 0;
}
思路二:看透本质,从大到小,统计需要的长度need4,need2,need1。算出能提供的sum4,sum2,sum1;(最坑的是此代码在vj上频频交不过,在codeforces上立马过了,可能是那段时间服务器太卡了)

详见代码:

#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;

int main(){
    int n,k;
    int a[105];
    int need1,need2,need4,sum2,sum1;
    while(~scanf("%d%d",&n,&k))
    {
        need1=need2=need4=0;
        for(int i=0;i<k;i++){
            scanf("%d",&a[i]);//分别统计需要的个数
            need4+=a[i]/4;  a[i]=a[i]%4;
            need2+=a[i]/2;  a[i]=a[i]%2;
            need1+=a[i]/1;  a[i]=a[i]%1;
        }
        sum2=2*n;
        sum1=0;
        if(n>=need4){//多出了的匀给后面的2和1,不够的从2里借,下面2的处理同理。
            sum2+=n-need4;
            sum1+=n-need4;
        }
        else
            sum2-=2*(need4-n);
        if(sum2>=need2)
            sum1+=sum2-need2;
        else
            sum1-=2*(need2-sum2);
        if(sum1>=need1)
            printf("YES\n");
        else
            printf("NO\n");
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值