算法心得:学霸vs学神,善学vs天生

你可以通过磨练打造一个高级特种兵,但天才特种兵却不可打造而出。

因为他的脑回路从生下来~5岁,就大部分定型了。各有所长,因材施教。玩游戏,点技能点也有先后顺序。

贪心算法

  1. 牌堆移动
    比较容易想,优先满足自己局部情况,不惜一切代价,比如可以先“借”右边的牌过来,即使右边的牌堆是负数个牌也不怕。之所以贪心能做到最优解,是因为本题满足欧几里得距离(或曼哈顿距离)的前提:把牌堆的左右移动看成地图中的向上/向右移动,总的最优步数是斜对角线,但可以有很多种移牌方法。

  2. 慢船渡河
    贪心我只想到了:总是让最快的人划回来,反复利用最快的人(不知道他会不会累死)。却很难想到另一种“同类相抵”的情况:由于2人共划船时是按船上慢的那个人来算,所以也可以先来也匆匆去也匆匆,然后再让最快的搭一个最慢的。
    之所以没想到是因为我是按2个人/每次来回来算的。而解法却是3个人/每2次来回来算的。只能说想得到的人,必定是善于观察生活、善于思考的慧识之人吧。

动态规划

动态规划三要素:

  1. 状态表示 dp[i],dp存储价值/权重,i存储状态/第几轮,(i的状态压缩)
  2. 迭代公式dp[i]=func(dp[i],dp[i-1]),若无法计算则你选的状态表示不当;一般都是前驱依赖。
  3. 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即可

棋盘覆盖问题,分治递归

  1. 一开始想的是从左到右的朴素填充法,毕竟先放边框四个角,然后水平扫描
  2. 听老师讲的后恍然大悟,分治本质上是:先假设最简单的4个格子情形,然后写最小逻辑,然后写能形成递归的逻辑。最难想的是,用分治写,若特殊方块不在该区块内,还需要自己填一个特殊方块,我以为必须在一个IF语句中,一次性把L形状全填满。其实答案的写法就是判断4次,一步一步填3个方块。
posted @ 2023-11-07 08:29  Nolca  阅读(25)  评论(0编辑  收藏  举报