ACM——贪心

Fishing Master(2017ccpc网络赛1008)

原题链接
题目大意:输入抓鱼的时间和煮每条鱼的时间,输出抓鱼和煮鱼所花的最短的时间。

Sample Input
2//样例个数
3 5//3条鱼,每抓一条鱼3分钟
5 5 8//3条鱼分别需要的煮的时间
2 4
3 3
Sample Output
23 11

题解贪心
每条鱼都需要被抓上来并且煮足够的时间,而我们能在炖鱼的时候抓鱼,所以至少需要抓一条鱼的时间和炖所有鱼的时间。要能在这个时间内就完成,则除了抓第一条鱼以外抓鱼的时候锅里都必须在炖鱼(假设锅里的鱼一旦炖好就自动取出来),显然如果 ti都太小的时候这是不能做到的,会有一些抓鱼的时间锅里没有在炖鱼,我们称锅里没有炖鱼的抓鱼时间为被浪费的时间T,所以我们的优化目标就是使被浪费的总时间T最小
对于第 i条鱼,炖它的时候我们可以不浪费时间抓到 ti/k条鱼,或者浪费 k-ti%k的时间抓到ti/k+1条鱼。所以如果炖所有鱼的时间/k>=n-1,则可以不浪费时间完成任务;
否则,则差m条鱼就选炖 ti%k前 m大的鱼的时候浪费时间多抓一条鱼。

#include <set>
#include <map>
#include <queue>
#include <cmath>
#include <cstdio>
#include <string>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

#define ll long long
#define pii pair<int, int>
#define pll pair<ll, ll>
#define mid (r+l)*0.5
#define l (d<<1)
#define r ((d<<1)&1)

const int N=100007;
const int M=100007;
const int inf=0x3f3f3f;
const double eps=1e-6;

#define ind(x) scanf("%d",&x)
#define inlf(x) scanf("%lf",&x)
#define inlld(x) scanf("%lld",&x)
#define ins(s) scanf("%s",s)
#define outd(x) printf("%d ",x)
#define outlf(x) printf("%lf\n",x)
#define outlld(x) printf("%lld\n",x)
#define outs(s) printf("%s",s)

ll gcd(ll a,ll b)
{
    return b==0?a:gcd(b,a%b);
}

vector<int> ve;
ll a[N];
bool ch[N];

int main()
{
    int t;
    ind(t);
    while(t--)
    {
        int n;
        ll k;
        ll ans=0;
        ind(n);inlld(k);
        int t=n;
        t-=1;//要抓的鱼 
        ans+=k;
        for(int i=1;i<=n;i++)
        {
            inlld(a[i]);
            cout<<t<<"#"; 
            if(t>0)
            {
                t-=a[i]/k;
                ans+=(a[i]/k)*k;
                a[i]%=k;
            }//煮鱼时间大于捕鱼时间的,需要捕鱼煮鱼同时进行,先加上捕鱼时间,a[i]更新为两数相除的余数 
        }
        sort(a+1, a+n+1);
        for(int i=n;i>=1;i--)
        {
            cout<<a[i]<<endl;
            if(t>0)//若还有鱼要抓,a[i]更新为更长的抓鱼时间,此时必须等待抓鱼完成才能煮 
            {
                a[i]=k;
                t--;
            }
            ans+=a[i];//最后加上需要等待的煮鱼时间 
        }
        outlld(ans);
    }
    return 0;
}

Largest Point_HDU5461(结构体)

题目来源:HDU5461
贪心:用两个结构体来分别记录 at^2和bt的值,然后对每一个值都赋予一个flag表示下标,然后对两个结构体排序。如果两者的最大值flag下标不同,那么加一起就是结果,否则要比较a次大和b最大加和以及a最大和b次大加和,选择大的输出。
重写cmp函数,使结构体升序排序。

#define ll long long int
#include <iostream>
#include<stdio.h>
#include<string.h>
#include <cmath>
#include <algorithm>
using namespace std;

struct date{
	ll date,flag;
}a[1000005],b[1000005]; 
ll t[1000005];
int cmp(date a,date b){
	return a.date<b.date;
}
int main(){
	int T;
	int num=0;
	scanf("%d",&T);
	while(T--){
		ll n,x,y;
		scanf("%lld%lld%lld",&n,&x,&y);
		for(int i=0;i<n;i++){
			scanf("%lld",&t[i]);
			a[i].date=t[i]*t[i]*x;
			b[i].date=t[i]*y;
			a[i].flag=i;b[i].flag=i;
		}
		sort(a,a+n,cmp);
		sort(b,b+n,cmp);
		if(a[n-1].flag!=b[n-1].flag){
			printf("Case #%d: %lld\n",++num,a[n-1].date+b[n-1].date);
		}
		else{
			ll ma=max(a[n-2].date+b[n-1].date,a[n-1].date+b[n-2].date);
			printf("Case #%d: %lld\n",++num,ma);
		}
	} 
}
发布了54 篇原创文章 · 获赞 26 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/weixin_43629813/article/details/100084677