这周三场牛客比赛加一块还没有到两位数的AC,难以言表,只能学学dp过过日子了。
其实在这之前我以为dp很难,不太会接触到,结果场场有dp,所以被迫营业,强行啃了点dp。
dp相对于常规算法来说,效率会高出一截,原因就在于他通过储存计算过的数据,来避免重复的操作,因此大大简化了程序,但是dp也有限制,只有在当第k项成立时,第k-1项也成立的情况下,dp才能发挥作用。
首先是第一道题,原题如下:
链接:https://ac.nowcoder.com/acm/contest/23106/A
来源:牛客网
现在,你是游戏的主角,淳平,你知道船上包括自己在内的n个人的手表数字,为了分析局势,你想要计算出可以打开1−9号门的人物组合有多少种,你可以完成这项任务吗?
此题首先要了解到,数字根等于它对9取模的值,然后解题。
在解题的最开始,需要做的事情就是判断题目的类型,因为本文主题是dp问题,所以这道题可以用dp(bushi。通过审题发现,如果用常规解法,组合情况过多,其中重复计算了很多遍数字和,而当我们将单个数字作为一项,那么就会产生选取这个数字和不选取这个数字两种情况,而每种情况所对应的前一项都是满足条件的相似结构,因此本题采用dp解法。
本题类似于背包问题,虽然当时我连数字根是对9取模都没发现,寄。
然后是下一道题,原题如下:
链接:https://ac.nowcoder.com/acm/contest/23478/B
来源:牛客网
- 购买一整个重量为wi的西瓜
- 把瓜劈开,购买半个重量为wi/2的西瓜
- 不进行购买操作
现在智乃想要知道,如果他想要购买西瓜的重量和分别为{k=1,2,3...M}时,有多少种购买西瓜的方案,因为这些数字可能会很大,请输出方案数对{10^9+7}取余数后的结果。
最惨的不是完全没有思路(比如说上一道),而是知道了这道题用的是dp,也知道了分哪几种情况,但是代码在心口难开。
首先,这道题用常规方法显然不行,而我们对每个瓜都可以进行一次选/不选/选1/2的决策,而每次决策的前一项也都是相同的决策,因此能够将这些数据储存,避免重复计算,即采用背包问题的算法。
这道题,笔者当时没想明白我要做一个什么样的数组,然后看到了题解,其中的dp[i]表示第i个西瓜时的重量,而对每一项,进行一次分类,分别对大于西瓜重量、大于1/2西瓜重量以及小于1/2西瓜重量,递推前一项的数据,说起来是挺好懂的,然而笔者愣是折腾一小时没整出来。
本来是有第三题的,但是一直到我写这篇文章的时候,还没有搞懂这道题的解法,挖个坑,希望下周能搞明白。
浙公网安备 33010602011771号