算法心得:学霸vs学神,善学vs天生
你可以通过磨练打造一个高级特种兵,但天才特种兵却不可打造而出。
因为他的脑回路从生下来~5岁,就大部分定型了。各有所长,因材施教。玩游戏,点技能点也有先后顺序。
贪心算法
-
牌堆移动
比较容易想,优先满足自己局部情况,不惜一切代价,比如可以先“借”右边的牌过来,即使右边的牌堆是负数个牌也不怕。之所以贪心能做到最优解,是因为本题满足欧几里得距离(或曼哈顿距离)的前提:把牌堆的左右移动看成地图中的向上/向右移动,总的最优步数是斜对角线,但可以有很多种移牌方法。 -
慢船渡河
贪心我只想到了:总是让最快的人划回来,反复利用最快的人(不知道他会不会累死)。却很难想到另一种“同类相抵”的情况:由于2人共划船时是按船上慢的那个人来算,所以也可以先来也匆匆去也匆匆,然后再让最快的搭一个最慢的。
之所以没想到是因为我是按2个人/每次来回来算的。而解法却是3个人/每2次来回来算的。只能说想得到的人,必定是善于观察生活、善于思考的慧识之人吧。
动态规划
动态规划三要素:
- 状态表示 dp[i],dp存储价值/权重,i存储状态/第几轮,(i的状态压缩)
- 迭代公式dp[i]=func(dp[i],dp[i-1]),若无法计算则你选的状态表示不当;一般都是前驱依赖。
- If语句
求组合数
由数学公式易知:C(n, k) = C(n - 1, k - 1) + C(n - 1, k),可用一维数组优化,注意因为使用到j-1前驱依赖,为了防旧数据被污染,保证一定使用的是上一轮的数据,需要逆向迭代。
还可以用min(i,k),在k行之后减少运算量。
求最少纸币个数
以金额amount为数组下标,公式min(self,count[i-coins[j]]+1),注意检查count[i-coins[j]]!=INT_MAX。由于以amount为下标,每次count[i]+1即可
棋盘覆盖问题,分治递归
- 一开始想的是从左到右的朴素填充法,毕竟先放边框四个角,然后水平扫描
- 听老师讲的后恍然大悟,分治本质上是:先假设最简单的4个格子情形,然后写最小逻辑,然后写能形成递归的逻辑。最难想的是,用分治写,若特殊方块不在该区块内,还需要自己填一个特殊方块,我以为必须在一个IF语句中,一次性把L形状全填满。其实答案的写法就是判断4次,一步一步填3个方块。
本文作者:Nolca
本文链接:https://www.cnblogs.com/nolca/p/17814225.html
版权声明:本作品采用 收益分享revenue sharing 许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步