【题解】PIZZA 贪心

题目描述

Michael请N个朋友吃馅饼,但是每个朋友吃且仅吃一个馅饼的1/4、1/2或3/4。请你编程求出Michael至少需要买多少个馅饼。

输入输出格式

输入格式:

输入文件的第一行是整数N;接下来的N行中,每行都是1/4、1/2或3/4。

输出格式:

输出文件仅有一行包含一个整数——至少需要购买的馅饼数目。

输入输出样例

输入样例#1: 复制

6
3/4
1/2
3/4
1/2
1/4
1/2

输出样例#1: 复制

4

说明

1 ≤ N ≤ 10,000

思路

  • 简单贪心但要注意细节讨论

贪心:

  • 考虑到3/4块的要么与1/4的配对成一块,要么单独作为一块;
  • 同时与1/2,1/4相比更容易使代价增加(即期望更大),所以要优先处理3/4

之后我分情况讨论了一下

  • 若一开始1/4的就比3/4的少,
    • 那么处理完第一步后,1/4已经被消耗完.只可能剩下1/2与3/4大小的.
    • 对于1/2块的考虑与自己配对
    • 最后加上没能配对的1/2和第一步后剩下的3/4
  • 若刚开始时1/4比3/4多
    • 第一步后只剩下了1/4与1/2大小的
    • 先考虑两个1/4与一个1/2组成一队
    • 在分别与自己配对
    • 最后根据情况得到ans

代码

#include<cmath>
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
#define re register int
using namespace std;
inline int read(){
    int x=0,w=1;
    char ch=getchar();
    while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
    if(ch=='-') w=-1,ch=getchar();
    while(ch>='0'&&ch<='9') x=(x<<1)+(x<<3)+ch-48,ch=getchar();
    return x*w;
}
int sum_1,sum_2,sum_3,ans=0;
char s[5];
int main(){
    freopen("T21330.in","r",stdin);
    int n;
    n=read();
    for(re i=1;i<=n;++i) {
        scanf("%s",s);
        if(s[0]=='1'&&s[2]=='4') sum_1++;
        if(s[0]=='1'&&s[2]=='2') sum_2++;
        if(s[0]=='3'&&s[2]=='4') sum_3++;
    }
    int ans=0;
    if(sum_1>sum_3) {
        ans+=sum_3;
        sum_1-=sum_3;
        sum_3=0;
    }else {
        ans+=sum_1;
        sum_3-=sum_1;
        sum_1=0;
    }
    if(sum_1==0) {
        ans=ans+(sum_2/2)+(sum_2%2)+sum_3;
        printf("%d\n",ans);
        return 0;
    } else {
        while(sum_1>=2&&sum_2>=1) {
            ans++;
            sum_1-=2;
            sum_2-=1;
        }
        ans+=sum_1/4+sum_2/2;
        sum_1%=4;
        sum_2%=2;
        if((sum_1==0||sum_1==1)&&(sum_2!=0)) {printf("%d\n",ans+1);return 0;}
        if(sum_1!=0&&sum_2==0) {printf("%d\n",ans+1);return 0;}
        //ans=ans+sum_2;
        //printf("%d\n",ans);
        return 0;
    }
    
}
c++

 

posted @ 2018-02-28 11:43  bbqub  阅读(246)  评论(0编辑  收藏  举报