# 刷题记录——9.29

poj2079(贪心)
poj1700(贪心)


 1. poj2079
    题意理解挺久的,在纠结needed colors是什么情况,后来看网上人说的才知道,是用来规定下限的……从题目方面感觉没什么意义啊,可能在运行上减少了点运算,出题者的善心?


恩。。。一开始以为needed colors是在配好gray之后还要剩下那么多ml,想说排个序,两端扫一遍,用最大的三个减去最小的那个数,然后看到最后一个样例……完全不行啊。后来写写画画发现,每次配的量少一点,而且是用量最多的三个去配,结果会比较大。
1A诶,好开心O(∩_∩)O~~
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    int n,need[13],g,get;
    bool cmp(int x,int y){
    return x>y;
    }
    int main(){
        int i,m;
        while(scanf("%d",&n),n){
            scanf("%d",&need[0]);
            m=need[0];
            get=0;
            for(i=1;i<n;i++){
                scanf("%d",&need[i]);
                m=(m<need[i])?need[i]:m;
            }
            scanf("%d",&g);
            if(m%50==0)
                m/=50;
            else
                m=m/50+1;
                
            for(i=0;i<n;i++)
                need[i]=m*50-need[i];
                
            while(1){
            	if(get == g)
                    break;
                sort(need,need+n,cmp);
                if(need[0]<=0 || need[1]<=0 || need[2]<=0){
                    m++;
                    for(i=0;i<n;i++)
                        need[i]+=50;
                }
                need[0]--;
                need[1]--;
                need[2]--;
                get++;
            }
            
            printf("%d\n",m);
        }
    }


    
 2. poj1700
    乘船过河问题。只有一条船,船上最多只能有两个人,过河时间按划船较慢的人的划船时间来算。
    看的网上的题解才过的,现在也不是很懂。。。
    最优解的问题,用贪心的话就是把大问题化成小问题,取每个小问题的最优解,从而得到大问题的最优解。
    首先,要把N个人过河的问题,转化为几组人过河的问题,每一组的情况都是一样的或者是有可以递归循环的规律,才能通过小组最优解得到整体最优解。网上的思路是这样的:
    n>=4:
    ,假设n个人单独过河所需要的时间存储在数组p中,将数组p按升序排序,那么 这时将单独过河所需要时间最多的两个旅行者送到对岸去,有两种方式:
      1> 最快的(即所用时间p[0])和次快的过河,然后最快的将船划回来,再次慢的和最慢的过河,然后次快的将船划回来.
        即所需时间为:p[0]+2*p[1]+p[n-1]
      2> 最快的和最慢的过河,然后最快的将船划回来,再最快的和次慢的过河,然后最快的将船划回来.
        即所需时间为:2*p[0]+p[n-2]+p[n-1]


n=1、2、3的情况答案很显然。


代码:
    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    using namespace std;
    
    int main(){
        int t,n,p[1000],ans,i;
        scanf("%d",&t);
        while(t--){
            scanf("%d",&n);
            for(i=0;i<n;i++)
                scanf("%d",&p[i]);
            ans=0;
            sort(p,p+n);
    
            for(i=n-1;i>2;i-=2)
                if(2*p[1]+p[0]+p[i] < 2*p[0]+p[i]+p[i-1])
                    ans+=2*p[1]+p[0]+p[i];
                else
                    ans+=2*p[0]+p[i]+p[i-1];
    
            if(i==2)
                ans+=p[0]+p[1]+p[2];
            else if(i==1)
                ans+=p[1];
            else
                ans+=p[0];
            printf("%d\n",ans);        
        }
    }


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值