题目: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\)。

核心代码:

if(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\)

#include<bits/stdc++.h>
#define ll long long
using namespace std;
int t,k,x1,x2,Max=1;
ll dp[100005],sum[100005];
int main(){
scanf("%d %d",&t,&k);
while(t--){
scanf("%d %d",&x1,&x2);
if(Max>=x2){ //优化:判断x2和max(x2)的大小
printf("%lld\n",(sum[x2]-sum[x1-1])%1000000007);
continue;//直接跳过
}
for(int i=Max;i<=x2;i++){//只计算没计算过的
if(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;
}
printf("%lld\n",(sum[x2]-sum[x1-1])%1000000007);
Max=x2;//更新Max的值
}
return 0;
}

究竟是什么地方错了?

然后你交上去发现WA了!

这也就是一个本蒟蒻在做题时犯的错误。

一般要取余的题都是一边计算一边取模,所以可能会造成dp数组中前面的值大于后面的值的情况。在最终计算 \(x_1\sim x_2\) 的时候做的减法运算可能是负数,负数取模就出事了。

那如何解决呢?其实很简单,只需要在取模之前再加上一个 \(1000000007\) 就可以了。

\(Code\)

#include<bits/stdc++.h>
#define ll long long
using namespace std;
int t,k,x1,x2,Max=1;
ll dp[100005],sum[100005];
int main(){
scanf("%d %d",&t,&k);
while(t--){
scanf("%d %d",&x1,&x2);
if(Max>=x2){
printf("%lld\n",(sum[x2]-sum[x1-1]+1000000007)%1000000007);
continue;
}
for(int i=Max;i<=x2;i++){
if(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;
}
printf("%lld\n",(sum[x2]-sum[x1-1]+1000000007)%1000000007);
Max=x2;
}
return 0;
}

终于A了!www

CF474D Flowers 题解的更多相关文章

  1. CF474D. Flowers

    D. Flowers time limit per test 1.5 seconds memory limit per test 256 megabytes input standard input ...

  2. Luogu CF451E Devu and Flowers 题解报告

    题目传送门 [题目大意] 有n种颜色的花,第i种颜色的花有a[i]朵,从这些花中选m朵出来,问有多少种方案?答案对109+7取模 [思路分析] 这是一个多重集的组合数问题,答案就是:$$C_{n+m- ...

  3. CF740B Alyona and flowers 题解

    Content 有 \(n\) 个数 \(a_1,a_2,a_3,...,a_n\),给定 \(m\) 个区间,你可以选择一些区间使得它们的总和最大(也可以不选),求这个最大的总和. 数据范围:\(1 ...

  4. [题解] [CF451E] Devu and Flowers

    题面 题解 就是一个求\(\sum_{i= 1}^{n}x _ i = m\)的不重复多重集的个数, 我们可以由容斥原理得到: \[ ans = C_{n + m - 1}^{n - 1} - \su ...

  5. 题解 【POJ1157】LITTLE SHOP OF FLOWERS

    先把题目意思说一下: 你有F束花,编号为\(1\)~\(F\)(\(1<=F<=100\)),\(V\)个花瓶,编号为\(1\) ~\(V\)(\(1<=V<=100\)), ...

  6. CF451E Devu and Flowers (隔板法 容斥原理 Lucas定理 求逆元)

    Codeforces Round #258 (Div. 2) Devu and Flowers E. Devu and Flowers time limit per test 4 seconds me ...

  7. Codeforces Round #381 (Div. 2)B. Alyona and flowers(水题)

    B. Alyona and flowers Problem Description: Let's define a subarray as a segment of consecutive flowe ...

  8. CF459B Pashmak and Flowers (水

    Pashmak and Flowers Codeforces Round #261 (Div. 2) B. Pashmak and Flowers time limit per test 1 seco ...

  9. Codeforces Round #271 (Div. 2)题解【ABCDEF】

    Codeforces Round #271 (Div. 2) A - Keyboard 题意 给你一个字符串,问你这个字符串在键盘的位置往左边挪一位,或者往右边挪一位字符,这个字符串是什么样子 题解 ...

随机推荐

  1. VRRP协议与原理

    VRRP协议与原理 目录: 一.VRRP协议概述 1.1.VRRP协议 1.2.单网关和多网关的缺陷 1.3.VRRP基本概述 二.VRRP工作原理 2.1.VRRP主备份备份工作工程 2.2.VRR ...

  2. 16、lnmp_mysql二进制安装

    16.1.lnmp介绍: lnmp架构,linux的php的程序架构: linux nginx MySQL PHP; # lamp:linux apache mysql php; 16.2.mysql ...

  3. 10、mysql增量恢复实战

    10.1.实验数据: mysql> select * from test; +----+------+------+ | id | name | age | +----+------+----- ...

  4. 初入web前端---实习(职场菜鹏)

    作为一个大四的准职场新人,顺利的找到了一份自己想从事的工作---web前端开发.

  5. Docker:Centos7更新yum源下载docker

    前言: Docker 要求 CentOS 系统(6.5及以上)的内核版本高于 3.10 ,查看本页面的前提条件来验证你的CentOS 版本是否支持 Docker . 通过 uname -r 命令查看你 ...

  6. PV操作的概念

    PV操作:一种实现进程互斥与同步的有效方法,包含P操作与V操作. P操作:使 S=S-1 ,若 S>=0 ,则该进程继续执行,否则排入等待队列. V操作:使 S=S+1 ,若 S>0 ,唤 ...

  7. XCTF crypto 不仅仅是Mors

    一. 题目暗示摩斯码,打开文件发现里面有反斜杠的.不管它直接拿来解密 二. 发现一句话是句英文,还有其他的加密方式,后面那串只有两种字符A和B,手抓饼A套餐,b套餐 培根加密,拿来解密后,得到flag

  8. buu Youngter-drive

    一.查壳,发现是upx的壳,用自解压方式,脱下壳 二.之后发现打不开了,应该是要修复,不想修复了,直接拖入ida 找到关键函数,中间发生一点小插曲,发现堆栈不平衡,然后导致F5反编译失败,百度了下是A ...

  9. 如何用jmeter监控内存,CPU(1)

    要jmeter的运行环境配置好就可以: 打开这个小工具的步骤很简单,如果你已经配置好了Jmeter运行的环境,那么你也就不用去做其他的配置,直接 点击:开始-->运行-->输入cmd--& ...

  10. 第三章 深入理解python语言

    计算机技术的演进过程 1946-1981年 计算机系统结构时代(35年) 解决计算机能力的问题 1981-2008年 网络和视窗时代(27年) 解决交互问题 2008-2016年 复杂信息系统时代(8 ...