• uva757


    题目:uva757 - Gone Fishing(贪心)


    题目大意:有N个湖泊仅仅有一条通路将这些湖泊相连。

    每一个湖泊都会给最開始5分钟间隔内能够调到的鱼(f)。然后给每过5分钟降低的鱼的数量(d),假设当前的鱼少于等于降低的数量,说明在下个5分钟没有鱼。还有过每条道路的所要耗费的时间(N-1),时间都是以5分钟为单位的。渔者能够在随意一个湖泊钓鱼,可是起始位置是在湖泊1。问H小时后,渔者如何合理的在每一个湖泊分配时间,能够得到的鱼最多。

    假设得到最多的鱼的方式有多种,则取在前面的湖泊耗时最久的那一种。


    解题思路:由于这些湖泊是由一条通路串起来的。这样就意味着经过湖泊3,那么的先经过湖泊2。

                      所以这里先枚举钓鱼的终点i。这样在路上耗费的时间就能够确定了。然后在0 - i这些湖泊中以f最大的排序。每次取都是f取最多的,直到和这个湖泊的鱼降低到和第二个大的f相等或者更小。这里有个注意点。两个湖泊假设f同样的话。应该先选比較前面的湖泊。

                     然后再进行排序。反复这些操作直到时间耗尽,或是没有湖泊有鱼。

                    这样就可能存在时间没实用完的情况。这个时候随意的湖泊都是没有鱼的,在哪个湖泊呆着都是一样的,可是由于要求的前面的湖泊耗时多,所以剩下的时间就都给湖泊1。

                    最后统计鱼的时候,大于当前的最大值自然要保存这样的分配方式,可是等于的话,就须要选择前面湖泊耗时较大的那种。

                    计算鱼的数量时候要细心。


    代码:

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    
    const int N = 30;
    int h, n;
    int t[N];
    typedef long long ll;
    ll fish;
    
    struct Lake {
    
    	int i;
    	ll f;
    	int d;
    	int hour;
    }l[N], l1[N];
    
    int cmp (const Lake &a, const Lake &b) { 
    	if (a.f == b.f)
    		return a.i < b.i;
    	return a.f > b.f; 
    }
    
    int cmp1 (const Lake &a, const Lake &b) { return a.i < b.i; }
    
    void init () {
    
    	h *= 12;
    	fish = -1;
    	for (int i = 0; i < n; i++)
    		l[i].hour = 0;
    }
    
    bool judge (int num, int newh) {          //同样鱼的数目的时候比較选择哪种方案
    
    	sort (l1, l1 + num + 1, cmp1);
    	l1[0].hour += newh;
    	for (int i = 0; i <= num; i++)
    		if (l1[i].hour != l[i].hour)
    			return l1[i].hour > l[i].hour;
    	return false;
    }
    
    void solve () {
    
    	init ();
    	int newh;
    	int k, max_day;
    	ll sum; 
    	
    	for (int i = 0; i < n; i++) {            //枚举终点
    
    		newh = h;	
    		for (int j = 0; j <= i; j++) {   
    
    			l1[j].i = l[j].i;
    			l1[j].f = l[j].f;
    			l1[j].d = l[j].d;
    			l1[j].hour = 0;
    		}
    
    		for (int j = 0; j <= i - 1; j++)  //路上要耗费的时间
    			newh -= t[j];
    		if (newh <= 0)
    			continue;                 //到达不了直接下一种方案
    
    		if (i == 0) {                     
    
    			l1[i].hour += newh;	
    			newh = 0;
    		}
    
    		while (newh > 0 && i) {              //找f最大的湖泊
    
    			sort (l1, l1 + i + 1 , cmp);       
    			if (l1[0].f == 0)
    				break;
    			if (l1[0].d != 0) {
    				
    				if (l1[0].f == l1[0].f)
    					k = 1;
    				else {
    
    					k = (l1[0].f - l1[1].f) / l1[0].d;
    					if ((l1[0].f - l1[1].f) % l1[0].d)
    						k++;
    				}
    			}
    			else
    				k = newh;           //假设d等于0说明这里的鱼不会降低。自然剩下的时间都耗费在这里最合理。

    if (newh - k < 0) k = newh; newh -= k; l1[0].f -= k * l1[0].d; //更新f和这个湖泊的耗时 if (l1[0].f < 0) l1[0].f = 0; l1[0].hour += k; } sum = 0; for (int j = 0; j <= i; j++) { //计算鱼的数目 k = l1[j].i; if (!l1[j].hour) continue; if (l[k].d == 0) { sum += l[k].f * l1[j].hour; continue; } max_day = l[k].f/ l[k].d; if (l[k].f % l[k].d != 0) max_day++; if (l1[j].hour <= max_day) max_day = l1[j].hour; l1[j].f = l[k].f - (max_day - 1) * l[k].d; sum += (l[k].f + l1[j].f) * max_day / 2; } if (sum > fish || (sum == fish && judge(i, newh))) { //维护最大值 fish = sum; for (int j = 0; j <= i; j++) { if (l1[j].i == 0) l[0].hour = l1[j].hour + newh; else l[l1[j].i].hour = l1[j].hour; } } } } int main () { bool flag = 0; while (scanf ("%d", &n) && n) { if (flag) printf (" "); flag = 1; scanf ("%d", &h); for (int i = 0; i < n; i++) scanf ("%lld", &l[i].f); for (int i = 0; i < n; i++) scanf ("%d", &l[i].d); for (int i = 0; i < n - 1; i++) scanf ("%d", &t[i]); for (int i = 0; i < n; i++) l[i].i = i; solve(); printf ("%d", l[0].hour * 5); for (int i = 1; i < n; i++) printf (", %d",l[i].hour * 5); printf (" "); printf ("Number of fish expected: %lld ", fish); } return 0; }



    版权声明:本文博主原创文章,博客,未经同意不得转载。

  • 相关阅读:
    Python strip()方法
    C#操作计划任务
    C# Task的用法
    C#异步编程之浅谈Task
    [深入学习C#]C#实现多线程的方法:线程(Thread类)和线程池(ThreadPool)
    [深入学习C#]C#实现多线程的方式:使用Parallel类
    详细的.Net并行编程高级教程--Parallel
    5天玩转C#并行和多线程编程 —— 第一天 认识Parallel
    C# 并行任务——Parallel类
    C#多线程--线程池(ThreadPool)
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/4872866.html
Copyright © 2020-2023  润新知