Riiichard

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

这周三场牛客比赛加一块还没有到两位数的AC,难以言表,只能学学dp过过日子了。

其实在这之前我以为dp很难,不太会接触到,结果场场有dp,所以被迫营业,强行啃了点dp。

dp相对于常规算法来说,效率会高出一截,原因就在于他通过储存计算过的数据,来避免重复的操作,因此大大简化了程序,但是dp也有限制,只有在当第k项成立时,第k-1项也成立的情况下,dp才能发挥作用。

首先是第一道题,原题如下:

链接:https://ac.nowcoder.com/acm/contest/23106/A
来源:牛客网

在打越钢太郎的著名解谜游戏系列《极限脱出》的第一作《九小时九个人九扇门》中,有这样一个有趣的设定:游戏中,9位主人公被困在一座大型的豪华巨轮中,每个人手上都有一个奇怪的手表,手表上有一个数字,9个人的数字分别是1−9;在巨轮中,还有很多紧闭的数字门,每扇数字门上也有一个1−9的数字,要想打开数字门逃出生天,主角们必须要满足一个奇怪的条件:

k个人能够打开门上数字为d的一扇数字门,当且仅当这k个人的腕表数字之和的数字根恰好为d。

一个数字的数字根是指:将该数字各数位上的数字相加得到一个新的数,直到得到的数字小于10为止,例如,149的数字根为149=>1+4+9=14=>1+4=5,故149的数字根为5。我们约定,小于10的数字,其数字根就为其本身。

例如,如果游戏中的一宫(手表数字为1)、四叶(手表数字为4)、八代(手表数字为8)三人组合在一起,就可以打开编号为4的数字门,这是因为1+4+8=13,而13的数字根为4

现在,你是游戏的主角,淳平,你知道船上包括自己在内的n个人的手表数字,为了分析局势,你想要计算出可以打开1−9号门的人物组合有多少种,你可以完成这项任务吗?

 

此题首先要了解到,数字根等于它对9取模的值,然后解题。

在解题的最开始,需要做的事情就是判断题目的类型,因为本文主题是dp问题,所以这道题可以用dp(bushi。通过审题发现,如果用常规解法,组合情况过多,其中重复计算了很多遍数字和,而当我们将单个数字作为一项,那么就会产生选取这个数字和不选取这个数字两种情况,而每种情况所对应的前一项都是满足条件的相似结构,因此本题采用dp解法。

本题类似于背包问题,虽然当时我连数字根是对9取模都没发现,寄。

然后是下一道题,原题如下:

链接:https://ac.nowcoder.com/acm/contest/23478/B
来源:牛客网

智乃来到水果摊前买瓜,水果摊上贩卖着{N}个不同的西瓜,第i{i}i个西瓜的重量为wi。智乃对于每个瓜都可以选择买一个整瓜或者把瓜劈开买半个瓜,半个瓜的重量为wi/2
也就是说对于每个西瓜,智乃都有三种不同的决策:
  1. 购买一整个重量为wi的西瓜
  2. 把瓜劈开,购买半个重量为wi/2的西瓜
  3. 不进行购买操作

为了简化题目,我们保证所有瓜的重量都是一个正偶数。

现在智乃想要知道,如果他想要购买西瓜的重量和分别为{k=1,2,3...M}时,有多少种购买西瓜的方案,因为这些数字可能会很大,请输出方案数对{10^9+7}取余数后的结果。

 

最惨的不是完全没有思路(比如说上一道),而是知道了这道题用的是dp,也知道了分哪几种情况,但是代码在心口难开。

首先,这道题用常规方法显然不行,而我们对每个瓜都可以进行一次选/不选/选1/2的决策,而每次决策的前一项也都是相同的决策,因此能够将这些数据储存,避免重复计算,即采用背包问题的算法。

这道题,笔者当时没想明白我要做一个什么样的数组,然后看到了题解,其中的dp[i]表示第i个西瓜时的重量,而对每一项,进行一次分类,分别对大于西瓜重量、大于1/2西瓜重量以及小于1/2西瓜重量,递推前一项的数据,说起来是挺好懂的,然而笔者愣是折腾一小时没整出来。

 

本来是有第三题的,但是一直到我写这篇文章的时候,还没有搞懂这道题的解法,挖个坑,希望下周能搞明白。

posted on 2022-01-30 23:52  Riiichard  阅读(34)  评论(0)    收藏  举报