贪心算法(hdu 4442 hdu 3183)

题目:http://acm.split.hdu.edu.cn/showproblem.php?pid=4442

题意:一个人去做运动,给定每项运动的初始等待时间和增长等待时间,一等完该运动的等待时间就相当于完成该项运动,即不考虑做运动的时间,求完成所有运动最短要多少时间。

题解:贪心,考虑两种运动,初始等待时间为a1,a2,增长等待时间为b1,b2,只会发生两种情况,先做第一个运动和先做第二个,先做第一个时间就为a1+a2+a1*b2(也可以写成a1+a2+a1*a2*(b2/a2)),同理另一种情况为a1+a2+a2*b1(a1+a2+a1*a2*(b1/a1)),所以可以发现,要使总时间最小,即是要考虑bi/ai最小,反过来ai/bi最大,大的放到后面等待即可,小的放到前面先执行,同理可得及时初始时间变化了t*bi也一样,这定理成立,所以只要考虑最初的ai/bi

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<queue>
#include<algorithm>
#define N 100005

using namespace std;
typedef struct
{
    int a,b;
    double d;
}Subject;
Subject s[N];
bool compare(Subject q,Subject w)
{
    return q.d<w.d;
}
const long long mod=365*24*60*60;
int main()
{
    int n;
    while(~scanf("%d",&n)&&n)
    {
        for(int i=1;i<=n;i++)
        {
            scanf("%d %d",&s[i].a,&s[i].b);
            s[i].d=(1.0*s[i].a)/(1.0*s[i].b);
        }
        sort(s+1,s+1+n,compare);
        long long sum=0;
        for(int i=1;i<=n;i++)
        {
            sum=(sum+s[i].a+sum*s[i].b)%mod;
        }
        printf("%lld\n",sum);
    }
    return 0;
}


题目:http://acm.split.hdu.edu.cn/showproblem.php?pid=3183

题意:给定一个数字,要求去掉其中的n个数,要求去掉后的数字最小

题解:贪心,可以发现只要考虑数字从前往后递减的情况,只要递减,就去掉前面大的数,当递增时先不用考虑,到最后得到递增数字只要从后往前继续去数字就能保证最小

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<queue>
#define N 1050
using namespace std;
char number[N];
char existence[N];
int main()
{
    int num;
    while(scanf("%s %d",number+1,&num)!=EOF)
    {
        int tail=2;
        int len=strlen(number+1);
        char last=number[1];
        existence[0]=last;
        int di=1;
        int count1=0;
        while(count1!=num&&tail<=len)
        {
            if(di>0&&last>number[tail])
            {
                di--;
                if(di!=0) last=existence[di-1];
                count1++;
            }
            else
            {
                existence[di++]=number[tail++];last=number[tail-1];
            }
        }
        if(tail>len&&count1!=num) {di=di-(num-count1);}
        else
        {
            for(int i=tail;i<=len;i++) existence[di++]=number[i];
        }
        int start=0;
        while(existence[start]=='0'&&start<di) start++;
        if(start>=di) printf("0");
        else
        {
            for(int i=start;i<di;i++)
            {
               printf("%c",existence[i]);
            }
        }
        printf("\n");
    }
    return 0;
}


 


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值