CF474D Flowers 题解
题目: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 题解的更多相关文章
- CF474D. Flowers
		
D. Flowers time limit per test 1.5 seconds memory limit per test 256 megabytes input standard input ...
 - Luogu CF451E Devu and Flowers 题解报告
		
题目传送门 [题目大意] 有n种颜色的花,第i种颜色的花有a[i]朵,从这些花中选m朵出来,问有多少种方案?答案对109+7取模 [思路分析] 这是一个多重集的组合数问题,答案就是:$$C_{n+m- ...
 - CF740B Alyona and flowers 题解
		
Content 有 \(n\) 个数 \(a_1,a_2,a_3,...,a_n\),给定 \(m\) 个区间,你可以选择一些区间使得它们的总和最大(也可以不选),求这个最大的总和. 数据范围:\(1 ...
 - [题解] [CF451E] Devu and Flowers
		
题面 题解 就是一个求\(\sum_{i= 1}^{n}x _ i = m\)的不重复多重集的个数, 我们可以由容斥原理得到: \[ ans = C_{n + m - 1}^{n - 1} - \su ...
 - 题解 【POJ1157】LITTLE SHOP OF FLOWERS
		
先把题目意思说一下: 你有F束花,编号为\(1\)~\(F\)(\(1<=F<=100\)),\(V\)个花瓶,编号为\(1\) ~\(V\)(\(1<=V<=100\)), ...
 - CF451E Devu and Flowers (隔板法 容斥原理 Lucas定理 求逆元)
		
Codeforces Round #258 (Div. 2) Devu and Flowers E. Devu and Flowers time limit per test 4 seconds me ...
 - 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 ...
 - CF459B Pashmak and Flowers (水
		
Pashmak and Flowers Codeforces Round #261 (Div. 2) B. Pashmak and Flowers time limit per test 1 seco ...
 - Codeforces Round #271 (Div. 2)题解【ABCDEF】
		
Codeforces Round #271 (Div. 2) A - Keyboard 题意 给你一个字符串,问你这个字符串在键盘的位置往左边挪一位,或者往右边挪一位字符,这个字符串是什么样子 题解 ...
 
随机推荐
- C#进阶学习4--反射(Reflection)
			
一.反射的定义 审查元数据并收集关于它的类型信息的能力. 二.基础概念 (1)Assembly:定义和加载程序集,加载在程序集中的所有模块以及从此程序集中查找类型并创建该类型的实例. (2)Modul ...
 - ubuntu 18.4LTS 安装12.1.6赛门铁克防病毒系统
			
创建/tools/ 文件夹,并将需要的软件包上传到该目录下 # mkdir -p /tools/ && cd /tools/ # tar -xzvf chang.tar.gz # cd ...
 - 5.15、tomcat下部署JPress
			
1.说明: jpress类似于wordpress,wordpress是php语言开发的国外开源软件,jpress是java语言 开发的国内开源软件: 2.下载软件包: [root@slave-node ...
 - 4、基本数据类型(init、bool)
			
4.1.数字: 1.age = 21 weight = 64 fight = 5 2.数字的特点: (1)数字是不可变数据类型(不可以增加,删除,修改元素) (2)数字可以直接访问 (3)数字不可使用 ...
 - Ant Design Blazor 组件库的路由复用多标签页介绍
			
最近,在 Ant Design Blazor 组件库中实现多标签页组件的呼声日益高涨.于是,我利用周末时间,结合 Blazor 内置路由组件实现了基于 Tabs 组件的 ReuseTabs 组件. 前 ...
 - Java hashCode&&equals
			
/** 为保证向Set中添加的对象其所在的类必须要重写hashCode和equals方法: 重写的原则:hashCode和equals尽量保持一致性: 两个相同的对象equals()返回true时,那 ...
 - Java运算中的类型转换
			
类型转换 运算中,不同类型的数据先转化为同一类型,然后进行运算 public class Dome04 { public static void main(String[] args) { //int ...
 - 并不是static final 修饰的变量都是编译期常量
			
见代码 public class Test { public static void main(String[] args){ // 情况一 基本数据类型 //System.out.println(O ...
 - 构建自己的dockerfile
			
一)创建自己的CentOS 构建dockerfile的原理图 Docker Hub中99%的镜像都是从FROM scratch这个基础镜像过来的.然后配置需要的软件和配置来进行构建. FROM #基础 ...
 - ADC电阻分压采集相关知识
			
1.电池串联可以增加电压,电池并联可以增加电流,都是为了增加电功率.但是电池不宜并联,即使是相同规格的电池,如果消耗不同,电势就会不同,会造成电池之间的放电现象. 2.电阻的作用: 限流:为使通过用电 ...