传送门:Problem H

https://www.cnblogs.com/violet-acmer/p/9664805.html

题意:

BaoBao在一条有刻度的路上行走(哈哈,搞笑),范围为

[0,n],且都是整数,在当前刻度i的前0.5米处(i+0.5)有红绿灯s[i+1],s[i+1]='0'代表红灯,s[i+1]='1'代表绿灯,遇到红灯需要等一秒变成绿灯后才可以来到i+1处。

每隔一秒所有的灯都会变色。

且没来到一个新的起点p,所有的灯都会恢复初始状态。

题解:

打表找规律:
对于样例3
t[0,1]=1
t[0,2]=3,t[1,2]=1
t[0,3]=4,t[1,3]=2,t[2,3]=2
t[0,4]=5,t[1,4]=3,t[2,4]=3,t[3,4]=1
t[0,5]=6,t[1,5]=4,t[2,5]=4,t[3,5]=2,t[4,5]=2
设dp[i]代表来到i处的总时间
例如
dp[1]=t[0,1]=1;
dp[2]=t[0,2]+t[1,2]=4;
dp[3]=t[0,3]+t[1,3]+t[2,3]=8;
dp[4]=t[0,4]+t[1,4]+t[2,4]+t[3,4]=12;
dp[5]=t[0,5]+t[1,5]+t[2,5]+t[3,5]+t[4,5]=18;

在计算dp[3]的时候
dp[3]所包含的所有时间为
t[2,3]
t[0,2]+t[2,3]
t[1,2]+t[2,3]
第一个t[2,3]容易计算,就是判断s[2]是红灯还是绿灯,红灯为2,绿灯为1;
t[0,2]+t[1,2]也容易计算,就是dp[2];

下面来求解后两个t[2,3]的计算:
设change[i,j]表示从i处到j处红绿灯变化的总次数;
计算第一个t[2,3]需要知道change[0,2],如果change[0,2]是奇数,则计算t[2,3]时原先的s[i]的红绿灯状态不变,反之,改变状态;
计算第二个t[2,3]亦是如此,需要知道change[1,2];

难点就在于change[0,2]与change[1,2];
计算容易发现change[0,2]=3,change[1,2]=1;
且通过计算其他的change[i,m](i<m)可以发现,change[0,m]与change[1,m],...,change[m-1,m]同奇偶,而change[m-1,m]与t[m-1,m]同奇偶
此时易得后两个t[2,3]的值是一样的,都和change[1,2]的奇偶以及s[2]状态有关。

故后两个t[2,3]的和x为
if(change[1,2]为奇) x=2*(s[i] == 1 ? 2:1);
else x=2*(s[i] == 1 ? 1:2);
合并为一句话就是
x=2*(s[2] == s[1] ? 1:2);

所以dp[i]=dp[i-1]+(i-1)*(s[i-1] == s[i-2] ? 2:1)+(s[i-1] == '1' ? 1:2);
最终结果是吧所有的dp[i]加起来(0<=i<=n)

AC代码:

 #include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#define exp 1e-8
#define mian main
#define pii pair<int,int>
#define pll pair<ll,ll>
#define ll long long
#define pb push_back
#define PI acos(-1.0)
#define inf 0x3f3f3f3f
#define w(x) while(x--)
#define int_max 2147483647
#define lowbit(x) (x)&(-x)
#define gcd(a,b) __gcd(a,b)
#define pq(x) priority_queue<x>
#define ull unsigned long long
#define scn(x) scanf("%d",&x)
#define scl(x) scanf("%lld",&x)
#define pl(a,n) next_permutation(a,a+n)
#define ios ios::sync_with_stdio(false)
#define met(a,x) memset((a),(x),sizeof((a)))
using namespace std;
const int maxn=1e5+; ll dp[maxn]; int main ()
{
int t;
scn(t);
string s;
while(t--)
{
cin>>s;
int len=s.length();
met(dp,);
dp[]=(s[] == '' ? :);
for(int i=;i<len;i++)
dp[i+]=dp[i]+i*((s[i]==s[i-])?:)+((s[i] == '') ? :); ll ans=;
for(int i=;i<=len;i++)
ans += dp[i];
printf("%lld\n",ans);
}
return ;
}

分割线:2019.5.8

一年的训练,思维开阔了不少;

今早醒来,我大致看了一下去年写的这篇题解;

感觉打表的暴力味很浓厚,缺乏一些证明;

昨天比赛的时候,依稀记得做过这道题;

还记得我写过题解,但,题解内容早已忘却;

无奈,重新找规律;

不过,这次不再是单纯的打表找规律,而是找了一下区间之间内在的联系;

回归正题;

定义 dp[ i ] 表示以 i 灯结尾所花费的总时间;(红绿灯的位置 1,2,.....,n)

dp[i]=[,i]+[,i]+....+[i-,i];//[x,i] 表示从x点开始,到达 i 灯所需的总花费

先来看看如下式子:

[x,i]与[y,i]同奇偶(x < i , y < i)

证明:

  不妨设 x < y,那么 [x,i] = [x,y]+[y,i]

  ①[y,i]为奇数

    如果[x,y]为奇数,那么,势必会改变[y,i]红绿灯的初始状态,[y,i]为偶数;

    如果[x,y]为偶数,那么,[y,i]的红绿灯状态就不会改变,[y,i]为奇数;

  ②[y,i]为偶数

    如果[x,y]为奇数,那么,势必会改变[y,i]红绿灯的初始状态,[y,i]为奇数;

    如果[x,y]为偶数,那么,[y,i]的红绿灯状态就不会改变,[y,i]为偶数;

  综上,[x,i]与[y,i]同奇偶,换句话说就是以第 i 个灯结尾的区间,同奇偶;

有了这个公式,这道题就解决一大半了;

假设dp[0,...,i-1]已求出,如何根据已求出的dp推导出dp[i]呢?

dp[i]=[0,i]+[1,i]+.....+[i-2,i]+[i-1,i]

    =[0,i-1]+[i-1,i]+[1,i-1]+[i-1,i]+....+[i-2,i-1]+[i-1,i]+[i-1,i]

    =[0,i-1]+[1,i-1]+....+[i-2,i-1]+[i-1,i]+[i-1,i]+....+[i-1,i]+[i-1,i]

=dp[i-1]+[i-1,i]+[i-1,i]+....+[i-1,i]+[i-1,i]

现在,问题的关键就在于如何求解不同的[i-1,i]所花费的时间;

根据上面推的公式可得:

  (1):[0,i-1],[1,i-1],.....,[i-2,i-1]同奇偶;

  (2):[0,i],[1,i],.....,[i-2,i],[i-1,i]同奇偶;

由这(1)(2)可得出:

  [i-1,i],[i-1,i],....,[i-1,i]同奇偶;

如何求出这(i-1)个的[i-1,i]是同奇还是同偶呢?

[i-2,i]与[i-1,i]同奇偶,即[i-2,i-1]+[i-1,i] 与 [i-1,i]同奇偶;

①[i-1,i]为偶数

  如果[i-2,i-1]为奇数,那么[i-1,i]为奇数;

  反之,[i-1,i]为偶数;

①[i-1,i]为奇数

  如果[i-2,i-1]为奇数,那么[i-1,i]为偶数;

  反之,[i-1,i]为奇数;

总结:如果[i-1,i]与[i-2,i-1]同奇偶,[i-1,i]为偶数,反之,[i-1,i]为奇数;

定义数组s,s[i]代表i处的红绿灯状况;

dp[i]=dp[i-1]+(i-1)*(s[i] == s[i-1] ? 2:1)+(s[i] == '1' ? 1:2);

AC代码:

 #include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#define ll long long
#define mem(a,b) memset(a,b,sizeof(a))
const int maxn=1e5+; char s[maxn];
ll dp[maxn]; ll Solve()
{
int len=strlen(s+);
mem(dp,);
dp[]=(s[] == '' ? :);///先求出dp[1]
for(int i=;i <= len;++i)
dp[i]=dp[i-]+(i-)*(s[i] == s[i-] ? :)+(s[i] == '' ? :); ll ans=;
for(int i=;i<=len;++i)
ans += dp[i]; return ans;
}
int main ()
{
int test;
scanf("%d",&test);
while(test--)
{
scanf("%s",s+);
printf("%lld\n",Solve());
}
return ;
}

2018.9青岛网络预选赛(H)的更多相关文章

  1. 2018.9青岛网络预选赛(K)

    传送门:Problem K https://www.cnblogs.com/violet-acmer/p/9664805.html 题意: 给你n个数,找出满足条件的最多的数的个数. 题解: 满足条件 ...

  2. 2018.9青岛网络预选赛(B)

    传送门:Problem(B) https://www.cnblogs.com/violet-acmer/p/9664805.html 参考资料: https://blog.csdn.net/qq_40 ...

  3. 2018.9青岛网络预选赛(A)

    传送门:Problem A https://www.cnblogs.com/violet-acmer/p/9664805.html 题意: 求m个PERFECTs中最多有多少个连续的PERFECT和最 ...

  4. 2018.9青岛网络预选赛(C)

    传送门:Problem C https://www.cnblogs.com/violet-acmer/p/9664805.html 题意: 定义五个指令,判断能否从输入的n条指令中成功跳出循环,如果不 ...

  5. 2018.9青岛网络预选赛(J)

    传送门:Problem J https://www.cnblogs.com/violet-acmer/p/9664805.html 题目大意: BaoBao和DreamGrid玩游戏,轮流按灯的按钮, ...

  6. 计蒜客 1460.Ryuji doesn't want to study-树状数组 or 线段树 (ACM-ICPC 2018 徐州赛区网络预赛 H)

    H.Ryuji doesn't want to study 27.34% 1000ms 262144K   Ryuji is not a good student, and he doesn't wa ...

  7. ACM-ICPC 2018 焦作赛区网络预赛 H题 String and Times(SAM)

    Now you have a string consists of uppercase letters, two integers AA and BB. We call a substring won ...

  8. ACM-ICPC 2018 徐州赛区网络预赛 H. Ryuji doesn't want to study

    262144K   Ryuji is not a good student, and he doesn't want to study. But there are n books he should ...

  9. ACM-ICPC 2018青岛网络赛-H题 Traveling on the Axis

    题目:略(不知道怎么从ZOJ搬题) 地址:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=4054 把这题的每个点分成两种情况 ...

随机推荐

  1. 2-Twenty third Scrum Meeting-20151229

    前言 因为服务器关闭至今,我们的开发项目也遭遇停滞一个星期.与网站开发负责人员协商之后,今天继续开放服务器.我们的项目也能够继续下去.比规定的开发时间(截止为2015/12/29)推迟,因此我们今天又 ...

  2. LINUX内核分析第六周学习总结——进程的描述与创建

    LINUX内核分析第六周学习总结--进程的描述与创建 标签(空格分隔): 20135321余佳源 余佳源 原创作品转载请注明出处 <Linux内核分析>MOOC课程 http://mooc ...

  3. Leetcode——66.加一

    @author: ZZQ @software: PyCharm @file: leetcode66_加一.py @time: 2018/11/29 16:07 要求:给定一个由整数组成的非空数组所表示 ...

  4. 用delete和trancate删除表记录的区别

    首先说相同点,就是他们都能删除表中的数据,区别有两点: 第一点: delete语句在删除记录的时候可以有选择的删除某些数据(使用where子句),当然,如果不添加where子句,就是删除所有记录 而t ...

  5. const修饰符与函数

    一.用const修饰函数的参数 函数参数类型前加const指明该参数为常量,在函数内部不可改变. void func(const int x) { //x不可以在内部进行赋值等操作. } 注:当参数为 ...

  6. CSS 范围选择器(自编)

    选择第一个到第六个li元素ul li:nth-child(n+3):not(:nth-child(n+6)){} 选择第二个到最后一个ul li:nth-child(2)~li{} 选择除了第一个和最 ...

  7. centos7黑客帝国装逼

    黑客帝国既视感 搜 cmatrix 然后放到本地解压缩 ,安装 yum install ncurses-devel./configure && make && make ...

  8. [转] python 模块学习 hashlib

    转自: http://www.cnblogs.com/BeginMan/p/3328172.html 一.hashlib概述 涉及加密服务:14. Cryptographic Services 其中 ...

  9. Kivy 中文教程 实例入门 简易画板 (Simple Paint App):3. 随机颜色及清除按钮

    1. 随机颜色 通过前面的教程,咪博士已经带大家实现了画板的绘图功能.但是,现在画板只能画出黄色的图案,还十分单调,接下来咪博士就教大家,如何使用随机颜色,让画板变得五彩斑斓. 改进后的代码如下: f ...

  10. JavaScript从入门到精通

    第一(基本语法) if(condition1){ expression1; }else if(condition2){ expression2; }else{ expression3; } switc ...