题目:CF474D Flowers
DP?递推?
首先可以很快看出这是一道 DP 的题目,但与其说是 DP,还不如说是递推。
大家还记得刚学递推时教练肯定讲过的一道经典例题吗?就是爬楼梯,一个有 $n$ 阶的楼梯,一个人爬上去,每次可以爬一阶也可以爬两阶,问有多少种爬法?其实这道题也是一样的,只不过把 $2$ 换成了 $k$ 而已。
于是我们开始分析,定义 $dp[i]$ 为吃 $i$ 个蛋糕的吃法总数。
很容易看出,如果 $i<k$,就不可以一口气吃掉,只能一个一个吃,方法为 $1$ 种。
如果 $i==k$,就既可以一个一个吃掉,也可以一口气全部吃完,方法为 $2$ 种。
如果 $i>k$,就有两种吃法,既可以先吃 $i-1$ 个,然后再吃一个,也可以先吃 $i-k$ 个,再吃 $k$ 个。方法为 $dp[i-1]+dp[i-k]$ 种。
最后记得要开 long long,而且要一边加一边模 $1000000007$。
核心代码:1
2
3
4
5
6
7
8if(dp[i])continue;
if(i<k)
dp[i]=1;
else if(i==k)
dp[i]=2;
else
dp[i]=(dp[i-1]+dp[i-k])%1000000007;
sum[i]=(sum[i-1]+dp[i])%1000000007;
因为一组数据只有一个 $k$,但是有很多组关于这个 $k$ 的测试点,所以可以用一个前缀和数组统计 $dp_1\sim dp_i$ 的和,然后根据题目中 $mod\ 1000000007$。
玄学优化
其实这个优化也不难想到。既然一组数据中只会有一个 $k$,那么说明不管怎么算,$dp[i]$ 的值算出来都是相等的。那么可以判断一下当前出现的最大 $x_2$,如果一组输入的 $x_2$ 值小于最大值,就说明 $dp[x_2]$ 已经计算过,直接输出即可。
Code
1 |
|
究竟是什么地方错了?
然后你交上去发现WA了!
这也就是一个本蒟蒻在做题时犯的错误。
一般要取余的题都是一边计算一边取模,所以可能会造成dp数组中前面的值大于后面的值的情况。在最终计算 $x_1\sim x_2$ 的时候做的减法运算可能是负数,负数取模就出事了。
那如何解决呢?其实很简单,只需要在取模之前再加上一个 $1000000007$ 就可以了。
$Code$
1 |
|
终于A了!www
这个人是个不可爱的 BUG 制造机,不过 TA 还是很喜欢瞎搞。
祝您拥有愉快的一天~