Gym 101490K Safe Racing (dp转换, 超超超级详细,包你看懂)
题意:给你一个长为L的圆形跑道,让你放置警示牌,相邻两个警示牌相隔距离不能超过S,让你求有多少种方案数放置。数据L,S都是1e6。
来个例子:L = 13, S = 5。一个圈表示长度为1。
思路:因为是一个圈,我们必须得判断最后一个牌子和第一个牌子的相距距离,所以如果我们规定了第一个放在那,最后一个放在那,这道题就简单多了。比如这个。
第一步思考:
1 当我们第一个放在1号位子时,我们最后一个能放的位置有12,13,14,15,16。
2 当我们第一个放在2号位子时,我们最后一个能放的位置有13,14,15,16。
3 当我们第一个放在3号位子时,我们最后一个能放的位置有14,15,16。
4 当我们第一个放在4号位子时,我们最后一个能放的位置有15,16。
5 当我们第一个放在5号位子时,我们最后一个能放的位置只有16。
6 当我们第一个放在6号位子时,不行,因为最大不能相差6,如果放在了6,我们得在1到5之间放置一个警示牌,和前面的情况已经重复了。

第二步思考:
确定了第一个位子和最后一个位子,你只需要确定中间能放置的种类不久行了吗?然后你想一会会发现这不就是求一个直行跑道放警示牌能放多少种吗?最多不能相隔s,你刚开始做dp时,每次上台阶你只能上1或者2阶,n阶的楼梯你可以走的方案数有多少种?这个题不就是你每次可以走1~S阶,求走n阶的方案数么?你的dp[i]表示的就是长度为i,在第i这个地方放置一个牌子的方案数。 所以dp[i]就等于dp[i-1]+dp[i-2]....+dp[i-s+1]啊。这不就写出来了吗?
需要注意的是,长度为三的,是有4个点,因为0可以放。

正常写是这样
dp[0] = 1;
for(int i = 1; i <= l; i++){
for(int j = i-1; j >= max(0, i-s); j--){
(dp[i] += dp[j]) %= mod;
}
}
但是复杂度肯定说不过去,再一想你想要的只不过要维护一个长为s的区间和而已,所以直接记录前s个的前缀和,然后每次加一个是,减去你维护的区间第一个值就行了。
dp[0] = now = 1;
for(int i = 1; i <= l; i++){
dp[i] = now;
(now += dp[i]) %= mod;
if(i >= s){ //维护长度为s的区间和。
now = (now - dp[i-s] + mod) % mod;
}
}
还记得第一步吗?

我们要的答案就是这些的对应位置的dp值相加。

就变成了:
1 当我们第一个放在1号位子时,我们最后一个能放的方案数有dp[11] + dp[12] + dp[13] + dp[14] + dp[15]
2 当我们第一个放在2号位子时,我们最后一个能放的方案数有dp[11] + dp[12] + dp[13] + dp[14]
3 当我们第一个放在3号位子时,我们最后一个能放的方案数有dp[11] + dp[12] + dp[13]
4 当我们第一个放在4号位子时,我们最后一个能放的方案数有dp[11] + dp[12]
5 当我们第一个放在5号位子时,我们最后一个能放的方案数有dp[11]
再开一个数组记录dp的前缀和就能直接算了。
这题就a了。
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const ll mod = 123456789;
const int maxn = 1e6 + 5;
ll dp[maxn], sum[maxn];
int main(){
ll l, s;
cin >> l >> s;
ll now = 1;
dp[0] = 1;
sum[0] = 1;
for(int i = 1; i <= l; i++){
dp[i] = now;
sum[i] = (sum[i-1]+dp[i]) % mod; // 前缀和
(now += dp[i]) %= mod;
if(i >= s){
now = (now - dp[i-s] + mod) % mod;
}
}
ll ans = 0;
for(int i = 1; i <= s; i++){
ans = (ans + sum[l-i] - sum[l-s-1] + mod)%mod;
}
cout << ans << endl;
return 0;
}
Gym 101490K Safe Racing (dp转换, 超超超级详细,包你看懂)的更多相关文章
- 问题 L: 超超的中等意思
问题 L: 超超的中等意思 时间限制: 1 Sec 内存限制: 128 MB提交: 366 解决: 27[提交] [状态] [命题人:jsu_admin] 题目描述 已知p,q,k和一个难搞得多项 ...
- 问题 F: 超超的自闭意思
问题 F: 超超的自闭意思 时间限制: 1 Sec 内存限制: 128 MB提交: 80 解决: 10[提交] [状态] [命题人:jsu_admin] 题目描述 质数定义为在大于1的自然数中,除 ...
- (原创)超详细一步一步在eclipse中配置Struts2环境,无基础也能看懂
(原创)超详细一步一步在eclipse中配置Struts2环境,无基础也能看懂 1. 在官网https://struts.apache.org下载Struts2,建议下载2.3系列版本.从图中可以看出 ...
- 利用树莓派来安装opencv从而来调动摄像头工作(没有坑,超超自己试过)
超超最近参加了学校里一位特别厉害的老师讲的课(两天,我就从一个小白然后了解了树莓派以及Arduino这些我之前都没有了解过的东西,由于结课的需要,我们需要自己设计一个创意以及完成作品)所以才有了这篇文 ...
- 水题 Gym 100553K Knockout Racing
题目传送门 /* 题意:有若干个点在一个区间内来回移动,1m/s. 水题:n^2的复杂度能解决,注意时间可能大于一个周期,要取模 */ #include <cstdio> #include ...
- UVA - 825Walking on the Safe Side(dp)
id=19217">称号: UVA - 825Walking on the Safe Side(dp) 题目大意:给出一个n * m的矩阵.起点是1 * 1,终点是n * m.这个矩阵 ...
- 对于挑战书上的很久之前都看不懂的DP看懂的突破
突破一..牢记问题概念 并且牢记dp状态方程 突破二..一直有一个求和dp转化成O1dp递推的式子看不懂.. 看不懂的原因是..没有分清求和符号作用的范围 提醒:以后遇到求和符号一定明确其求和的式子的 ...
- 小学生都能看懂的数位dp
前言 数位dp其实很久前就知道了,也做过几道和其他算法混在一起的题目,其实通过手玩是能做的 但毕竟是种算法,还是系统学下比较好(节省手玩时间) 模板题 P2602 [ZJOI2010]数字计数 化简题 ...
- JS 时间处理(GMT转换,超24小时加一天,时间差计算)
计算天数,加小时,加分数 Date.prototype.Format = function (fmt) { // author: meizz var o = { "M+": thi ...
- Codeforces Gym 100231L Intervals 数位DP
Intervals 题目连接: http://codeforces.com/gym/100231/attachments Description Start with an integer, N0, ...
随机推荐
- kafka常用命令(zookeeper与bootstrap-server)
在 0.9.0.0 之后的 Kafka,出现了几个新变动,一个是在 Server 端增加了 GroupCoordinator 这个角色,另一个较大的变动是将 topic 的 offset 信息由之前存 ...
- docker搭建phpswoole实现http服务
一.创建Dockerfile FROM phpswoole/swoole # COPY ./www/ /var/www/ 二.同级目录下创建docker-compose.yml services: p ...
- 基于工业5G网关的建筑机器人应用
建筑行业是世界上数字化程度最低.自动化程度最低的行业之一.近百年来,虽然技术革新不断,建筑本身的形态和功能也大不相同,但建筑施工的业态形式却始终没有出现显著的变化. 随着人口红利的消失,中国的建筑业面 ...
- 20211306 实验四 Python综合实践
学号 20211306 <Python程序设计>实验四报告 课程:<Python程序设计> 班级: 2113 姓名: 丁文博 学号:20211306 实验教师:王志强 实验日期 ...
- kali2020-bash: openvas-setup:未找到命令 ,解决办法
将openvas-setup命令换成 gvm-setup命令即可
- nvm在windows下安装与使用
1.卸载本地已经安装的所有node 2.nvm下载 下载地址https://github.com/coreybutler/nvm-windows ,选择nvm-noinstall.zip 放在本地盘, ...
- 收集的sql经典语句
经典SQL语句大全 一.基础1.说明:创建数据库CREATE DATABASE database-name 2.说明:删除数据库drop database dbname3.说明:备份sql serve ...
- C 语言 scanf 格式化输入函数
C 语言 scanf 格式化输入函数 函数概要 scanf 函数从标准输入流中读取格式化字符串.与 printf 格式化输出函数相反,scanf 函数是格式化输入函数. 函数原型 #include & ...
- python扑克牌
import random import operator def auto(): pokers=[] poker=[] for i in ['','','','']: for j in ['A',' ...
- Verilog中端口的连接规则
摘自于(15条消息) Verilog中端口应该设置为wire形还是reg形_CLL_caicai的博客-CSDN博客, 以及(15条消息) Verilog端口连接规则_「已注销」的博客-CSDN博客_ ...