zoukankan      html  css  js  c++  java
  • 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; }



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

  • 相关阅读:
    2019.6.20刷题统计
    36 线程 队列 守护线程 互斥锁 死锁 可重入锁 信号量
    35 守护进程 互斥锁 IPC 共享内存 的方式 生产者消费者模型
    34 进程 pid ppid 并发与并行,阻塞与非阻塞 join函数 process对象 孤儿进程与僵尸进程
    33 udp 域名 进程
    32 粘包 文件传输
    31 socket客户端. 服务器 异常 语法
    30 网络编程
    29 元类 异常
    26 封装 反射 常用内置函数
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/4872866.html
Copyright © 2011-2022 走看看