回复 50楼 C_printf
唉,你这孩子该怎么说你好呢。一瓶子不满,半瓶子晃荡。自己水平不行还不服别人,找各种借口抵赖。基本上就是欠骂的节奏。今儿让哥哥好好教教你。
就先从你那段自以为是的错误代码说起。咱们顺着往下一个函数一个函数说。
void de(vector(pair<int, int>>& data, int i)
辅助函数,用来从向量data中删除第i个元素。
我是根据你的代码逻辑来判断函数用途,从你的逻辑结构也能看出你的水平如何。仅这一个函数的构造就已经让我对你的能力评估大打折扣。
int ca(vector<pair<int,int>>& data,int d)
辅助函数,用来从向量data中查找一个权值最小的元素的索引。
这里的权值是指从剩下的歌里挑一首继续唱所用的时间(包括这首歌本身需要的时间和从上一首歌的单调d调整到当前歌的音调data[i].second所需的时间)。
int ss(vector<pair<int,int>> data,int last,int time)
仍然是一个辅助函数,也是你算法的核心部分。从剩余歌曲中挑一首加入到你已有歌单中用时最短的歌,然后将这首歌添加到你歌单的末尾。重复这一过程,直到所有歌都选完或歌单的时间已经超出了时限。返回值是你备选歌曲集中剩余歌曲的数量。
当然,歌单只是我为了描述方便的一个形象的说法,你在计算过程中只保留了最后一首歌的单调,以及唱完它后剩余的时限。
int s(int* d,int* t,int nums,int time)
主功能函数,遍历以每一首可选歌开始的、以ss的选歌方案筛选的歌单。返回剩歌最少的方案下剩歌的数量(剩歌最少的另一个意思当然就是歌单最长)。
main函数就不说了。虽然你写的依旧不满足题目要求,但今儿我的议题是算法,就不追究这些细枝末节的东西了。
你对我对你代码的分析有什么异议么?
ss就是一个错误的贪心方案,哪来的什么广度优先搜索?
用了递归充其量可以认为你是通过剪枝后的深度优先搜索。你的贪心方案可以看作是一个剪枝方案,而且还剪的就剩下一枝,去哪广去?
s中只是遍历以每个结点作为起始结点的情况,也只进行了一遍,你千万别跟我说这就是你认为的广搜。
证明一个算法正确并不容易,但证明一个算法错误就比较简单了,举个反例即可。
你这个搜索方案并不能达到最优。楼主已经以前面的贴子里公布了三组试例及正确结果,你至少该保证你的代码运行这三组试例能得到正确的结果吧?
5
1 6 7 6 1
1 2 3 4 5
25
这组你试过没?
就像你说感觉你的算法效率比我的高一样,你是个靠感觉编程的人,思考的深度太浅。想到一个解决方案也不论证一下它对不对就贸然编码,代码编出来也不仔细验证。这是很不负责任的行为,而且还要拿出来炫耀我就很鄙视了。
这两个贴子本不打算参与,就因为你在另一个贴子里贴了一段错的那么单纯的代码居然还敢霸气地和楼主要分,足见你内心的强大,于是决定和你聊聊。
说完你的错误,再说说效率的事。
你的算法要以每个结点作为起始结点进行一次遍历。遍历中一次添加一个结点,最多需要添加N次。为找到要添加的结点,需要遍历剩余结点,这个遍历过程也是N的线性函数。
综上,你的算法复杂度是O(N^3)。
而我的算法,你数数for循环的嵌套也能看出是O(N^2)。你说谁的效率高?
以上是算法效率的分析,咱再说说代码的效率。你动用了vector模板,而且在s函数中每次遍历前都克隆一遍datar,又而且在调用ss时data在实参到形参的传递过程又被克隆,呈递归的克隆。你知道这消耗了多少时间和空间资源吗?向量模板是个好东西,但是被你用糟蹋了。
所以,无论从哪个角度看,你的代码都没有效率优势,不知道你是怎么感觉出来的。
如果真想感觉一下,我可以给你构造一个有1000个元素的试例,你拿两段代码跑一下看看到底哪个快。
效率说完了,再扯扯这让我来气的代码风格的事。
我喜欢这么写,用不着你赞同。
高手并不是一定要这样写代码的。高手也并不是一定不要这样写代码的。这跟高不高手有毛关系?
别人看起来很费劲。如果我把代码展开了写你就能看懂的话,说一声我立马改写。
我出书肯定不这样写,但我现在不是在出书。
说到这里我要论说一个观点。
代码的书写主要是为了让人看,这没错。但是,“让人”并不是“让所有人”。
我将代码风格分成两类——工业类、艺术类。
工业类代码讲究的是简单可靠。你作为代码的生产者要尽量保证各种水平的使用者能接受。也是为了保证合作交流的顺畅才有了各种书写规范。
艺术类代码要传达的就不光是算法本身,也传达着作者的某种思想。它不只是用来看,更多是用来把玩、欣赏、品味的。它没那么多的受众,它只面向能接受它的人。
工业代码是流水线生产出来的,艺术代码属于手工孤品。
工业代码是本说明书,艺术代码是首散文。
工业代码是标准机打宋体字,艺术代码是手写魏碑、行书、草书...
我在这里写的代码有我自己的风格在里面,我的复合并不是随便乱复合。复合的过程中要用到一些平时少见的语法特性,想看懂我的代码需要有一定的基础。
换句话说,我没打算写那么直白的代码。
这里是论坛又不是工作中。这里不表现自我还在哪里表现?不在这里写自由的代码还在哪里写?
再者阅读代码也是一种能力,你看不懂的不是我的代码,而是我的代码所表达的算法。
你从代码反推算法的能力还太弱,所以即使我展开也没用。不用我更直白地说了吧?
你自己再慢慢想想这道题,把你的代码改对了。
重剑无锋,大巧不工