贪心整理&一本通1431:钓鱼——题解

摘要:
考虑到从哪个湖钓鱼5分钟,这相当于在路径1-˃2-˃3-˃…30tmpfish上钓鱼。push_back31}//为什么填写0?42磅鱼。push_back43for44if45{46tmphours=h-get[k];//可用纯捕捞时间47fortmpfish[i]=fish[i];//初始化48intsum=0;//记录当前答案49while50{51mava=-20000000;52mapo=0;53用于//贪婪选择54if55{56mava=tmpfish[i],57mapo=i;58}59ifbreak//如果没有鱼可捕,可以直接退出60sum+=mava;61iftmpfish[mapo]-=less[mapo];62elsetmpfish[mapo]=0;63t小时--;64}65ifmatt=和;66}67 elsebreak;68printf;69返回0;70}最后,让我们总结一下贪婪:贪婪策略的确定:当你看到问题时,你可以根据生活经验确认一个由直觉引导的贪婪策略(滑稽)。关于形而上学占卜贪婪的一些注释:贪婪只能在全局最优解可以从局部最优解导出时使用。

题目传送

 贪心整理&一本通1431:钓鱼——题解第1张

其实有一个更正经的题解

看了许久,发现这题貌似就是一个动态规划啊,但毕竟是贪心题库里的题,还是想想用贪心解吧。

经过(借鉴大佬思路)十分复杂的思考后,终于理解出了这题的贪心思路。该题的难点主要在最后可在任意湖边停住,而且不能往回走,在一个湖钓鱼时的效率还会越来越少。常规的思路看来是不行的了,题目好多动态未知的量,唯有我们更换角度,“化动为静”:

即然最后不知道停在哪个湖,那就分类讨论呗。把停在每个湖的最优解全部求出,在最后取个最优解不就行了吗?发现当我们知道主人公最后停在哪个湖后,她的路径也就唯一确定了(例如佳佳最后停在了第i个湖,那么她的路径一定是1—》2—》3—》。。。—》i),同时她的纯钓鱼时间可由总空闲时间减去行程时间唯一确定。考虑从哪个湖钓鱼一个5分钟,就相当于在路径1—》2—》3—》。。。—》i中的一个节点上“堆”上一个标记表示在这个湖又钓了5分钟的鱼,显然这里可用贪心策略,每次标记目前为止五分钟钓鱼数目最大的那个湖,并使当前记录答案的sumi+=在那个湖又钓的鱼数。最后比较所有的sumi(i=1,2,...,n)取最大的输出就行了。

还不懂?也许看看AC代码就懂了:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cctype>
 4 #include<vector>
 5 using namespace std;
 6 
 7 int ans;
 8 
 9 vector<int>fish,lesss,t;//每个湖第一个 5 分钟能钓到鱼的数量,每个湖每钓鱼5分钟较前5分钟钓的鱼数减少的数量,如题意 
10 vector<int>get,tmpfish;//从第一个湖走到第i个湖所需时间,每个湖的当前5分钟能钓到的鱼数 
11 
12 char ch;
13  
14 inline int read()//快读(亦名读入优化) 
15 {
16     ans=0;
17     ch=getchar();
18     while(!isdigit(ch)) ch=getchar();
19     while(isdigit(ch)) ans=(ans<<3)+(ans<<1)+ch-'0',ch=getchar();
20     return ans;
21 }
22 
23 inline void init()//初始处理动态数组,因为希望动态数组的下标从1开始 
24 {
25     fish.push_back(0);
26     lesss.push_back(0);
27     t.push_back(0);
28     get.push_back(0);
29     get.push_back(0);//注意get数组在主函数是从下标为2的开始处理的,因此需要多填一个0。 
30     tmpfish.push_back(0);
31 }//为什么要填0?为了与普通全局数组的性质相同(定义时默认全初始化为0) 
32 
33 int main()
34 {
35     init();
36     int n=read(),h=read()*12;
37     for(int i=1;i<=n;i++) fish.push_back(read());
38     for(int i=1;i<=n;i++) lesss.push_back(read());
39     for(int i=1;i<n;i++) t.push_back(read());
40     for(int i=2;i<=n;i++) get.push_back(get[i-1]+t[i-1]);
41     int mava,mapo,tmphours,matot=0;//当前贪心找到的最大值,当前贪心找到的最大值对应的下标(即湖的编号),当前纯钓鱼时间,最后的答案。 
42     for(int i=1;i<=n;i++) tmpfish.push_back(0);
43     for(int k=1;k<=n;k++)
44         if(h>get[k])
45         {
46             tmphours=h-get[k];//可用的纯钓鱼时间 
47             for(int i=1;i<=k;i++) tmpfish[i]=fish[i];//初始化 
48             int sum=0;//记录的当佳佳最后停在第k个湖时的当前答案 
49             while(tmphours>0)
50             {
51                 mava=-2000000000;
52                 mapo=0;
53                 for(int i=1;i<=k;i++)//贪心选择 
54                     if(mava<tmpfish[i])
55                     {
56                         mava=tmpfish[i];
57                         mapo=i;
58                     }
59                 if(mava<=0) break;//没鱼可钓就直接退出 
60                 sum+=mava;
61                 if(tmpfish[mapo]>lesss[mapo]) tmpfish[mapo]-=lesss[mapo];
62                 else tmpfish[mapo]=0;
63                 tmphours--;
64             } 
65             if(sum>matot) matot=sum;
66         }
67         else break;
68     printf("%d",matot);    
69     return 0;
70 }

最后再总结一下贪心吧:

贪心策略的确定:看到题时,可根据生活经验(滑稽)确认一个直觉指引的贪心策略。对付简单题很有用。

        关注一下与题目有关的性质(可以是由数学推导的式子,或是题中描述的物品的一些跟生活有关的物理性质)基本跟贪心有关的题都会有找某个方面的最大值或最小值。

贪心策略的证明: 直接数学推导。

        假设有一个更优的方案,反证。

        玄学占卜

贪心的几点注意:当整体最优解可由局部最优解推出(并不只局限与一种策略)时才可用贪心。(否则用动态规划)

        基本能用贪心的动态规划都行,不过一般贪心的复杂度要优于动态规划。

免责声明:文章转载自《贪心整理&amp;amp;一本通1431:钓鱼——题解》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇element ui的照片墙 默认显示照片【spring data jpa】使用jpa的@Query,自己写的语句,报错:org.springframework.expression.spel.SpelEvaluationException: EL1007E: Property or field 'status' cannot be found on null下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

动态规划-带权区间问题

一、动态规划算法的定义: 为了着手开发一个动态规划算法,我们需要一组从初始问题导出的满足某些基本性质的子问题。 只存在多项式个子问题 可以容易的从子问题的解计算出初始问题的解 在子问题中,从“最小”到“最大”存在一种自然的顺序,与一个容易计算的递推公式相联系。这个递推公式允许我们从某些更小的子问题的解来确定一个子问题的解。 二、带权区间调度问题: 我们...

luoguP3830 [SHOI2012]随机树 期望概率 + 动态规划 + 结论

题意非常的复杂,考虑转化一下: 每次选择一个叶节点,删除本叶节点(深度为$dep$)的同时,加入两个深度为$dep + 1$的叶节点,重复$n$轮 首先考虑第$1$问,(你看我这种人相信数据绝对是最大的数据,直接$f[i][S]$表示$i$个叶子结点,深度之和为$j$的时候的概率,然后化前缀和化出来...) 对于一个深度为$x$的点,对它操作后,深度增...

数字组合(动态规划)

数字组合 时间限制: 1 Sec  内存限制: 256 MB提交: 30  解决: 24[提交][状态][讨论版] 题目描述 在 N个数中找出其和为M的若干个数。先读入正整数N(1<N<100)和M(1<M<10000), 再读入N个正数(可以有相同的数字,每个数字均在1000以内), 在这N个数中找出若干个数, 使它们的和是M,...

动态规划解决01背包问题

一、问题描述:有n 个物品,它们有各自的重量和价值,现有给定容量的背包,如何让背包里装入的物品具有最大的价值总和? 二、总体思路:根据动态规划解题步骤(问题抽象化、建立模型、寻找约束条件、判断是否满足最优性原理、找大问题与小问题的递推关系式、填表、寻找解组成)找出01背包问题的最优解以及解组成,然后编写代码实现; 三、动态规划的原理及过程: eg:numb...

笔试算法题(44):简介

议题:动态规划(Dynamic Programming) 分析: DP主要用于解决包含重叠子问题(Overlapping Subproblems)的最优化问题,其基本策略是将原问题分解为相似的子问题,通过求解并保存最简单子问题的解,然后逐步合并成为原问题的解,由于需 要查询子问题的解,所以需要一个表格记录子问题的解;DP仅适用于最优子结构问题(Optim...

Max Sum Plus Plus (动态规划) HDU1024

题目来源:http://acm.hdu.edu.cn/showproblem.php?pid=1024 (http://www.fjutacm.com/Problem.jsp?pid=1375) 题意:长度为n的序列里,m段不相关区间的最大和 思路:我们先要确定一个东西,就是状态,这里我用dp[i][j]表示前j个数在取a[j]情况下分i段的最大和; 那么...