T1:队长快跑

基本思路:

  离散化·DP·数据结构优化DP

  这三个我都没想到。。。。气死。

  定义状态数组:\(c[i][j]\)表示在i时最小的a值是j时可以摧毁的最多的水晶数。

  那么状态转移方程就是:

c[i][j]=max(c[i-1][a[i]+1],c[i-1][a[i]+2],......,c[i-1][maxn])+1,if(a[i]>b[i]),这时还要同时更新c[i-1][j](j\(\in(b[i],a[i]]\))

c[i][j]=max(c[i-1][b[i]+1],c[i-1][b[i]+2],......,c[i-1][maxn])+1,if(a[i]<=b[i])

  我来解释下为什么这么转移:

首先可以明确的一点是,c[i][a[i]]只能由c[i-1][a[i]+1->maxn]转移来,因为如果转移的j比a[i]小,那么转移来的情况就不是以a[i]为最小值了。

加一是将当前点纳入

当a[i]<=b[i]时,我解释下什么是b[i]+1而不是a[i]+1,因为题目要求是之前的a比现在的b大,所以这么转移才合法

当a[i]>b[i]时,在b[i]~a[i]的范围内,c[i-1]是可以将当前点纳入的,所以要给他们集体加一,c[i][a[i]的转移就很好理解了

  直接转移时间复杂度是\(O(n^{3})\),考虑优化,我们可以将第二维放在线段树上,对应的叶子维护对应a值情况的值,一棵线段树从头用到尾,记录的是当前的情况,就可以\(O(nlogn)\)转移了。

  上代码:

#include<bits/stdc++.h>
using namespace std;
namespace STD
{
#define ll long long
#define rr register
inline int max(int x,int y){return x>y?x:y;}
//伤心往事:
//这里的max原本用的是#define函数,然后TLE了
//后来小马告诉我,#define函数会重复调用,T到起飞
//所以改成了inline
const int SIZE=100002;
int n;
int a[SIZE],b[SIZE];
int c[SIZE<<1];
int read()
{
rr int x_read=0,y_read=1;
rr int c_read=getchar();
while(c_read<'0'||c_read>'9')
{
if(c_read=='-') y_read=-1;
c_read=getchar();
}
while(c_read<='9'&&c_read>='0')
{
x_read=(x_read*10)+(c_read^48);
c_read=getchar();
}
return x_read*y_read;
}
int lazy[SIZE<<3],maxn[SIZE<<3];
void push_down(int id)
{
if(!lazy[id]) return;
lazy[id<<1]+=lazy[id],lazy[id<<1|1]+=lazy[id];
maxn[id<<1]+=lazy[id],maxn[id<<1|1]+=lazy[id];
lazy[id]=0;
return;
}
void add(int id,int l,int r,int st,int en,int val)
{
if(st<=l&&r<=en){maxn[id]+=val,lazy[id]+=val;return;}
int mid=(l+r)>>1;
push_down(id);
if(st<=mid) add(id<<1,l,mid,st,en,val);
if(mid<en) add(id<<1|1,mid+1,r,st,en,val);
maxn[id]=max(maxn[id<<1],maxn[id<<1|1]);
}
void change(int id,int l,int r,int pos,int val)
{
if(l==r){maxn[id]=max(maxn[id],val);return;}
int mid=(l+r)>>1;
push_down(id);
if(pos<=mid) change(id<<1,l,mid,pos,val);
else change(id<<1|1,mid+1,r,pos,val);
maxn[id]=max(maxn[id<<1],maxn[id<<1|1]);
}
int query(int id,int l,int r,int st,int en)
{
if(st<=l&&r<=en) return maxn[id];
int mid=(l+r)>>1;
int ret=INT_MIN;
push_down(id);
if(st<=mid) ret=max(ret,query(id<<1,l,mid,st,en));
if(mid<en) ret=max(ret,query(id<<1|1,mid+1,r,st,en));
return ret;
}
};
using namespace STD;
int main()
{
n=read();
for(rr int i=1;i<=n;i++)
{
a[i]=read(),b[i]=read();
c[++c[0]]=a[i],c[++c[0]]=b[i];
}
sort(c+1,c+1+c[0]);
int cnt=unique(c+1,c+1+c[0])-c-1;
for(rr int i=1;i<=n;i++)
{
a[i]=lower_bound(c+1,c+1+cnt,a[i])-c;
b[i]=lower_bound(c+1,c+1+cnt,b[i])-c;
}
int val;
for(rr int i=1;i<=n;i++)
{
if((a[i]<=b[i])&&(b[i]+1<=cnt))
{
val=query(1,1,cnt,b[i]+1,cnt)+1;
change(1,1,cnt,a[i],val);
}
if(a[i]>b[i])
{
add(1,1,cnt,b[i]+1,a[i],1);
//注意要先add后change,因为change后的树现在的情况了
//而add是给之前的情况add
if(a[i]+1<=cnt)
{
val=query(1,1,cnt,a[i]+1,cnt)+1;
change(1,1,cnt,a[i],val);
}
}
}
printf("%d",maxn[1]);
}

T2:影魔

  由于要用到可持久化线段树,我们没学,先鸽掉。

T3:抛硬币

基本思路:

  一个简单的小DP。

  定义状态数组:\(c[i][j]\)表示在i位置长度为j的本质不同的子序列的个数。

  很容易想出方程\(c[i][j]=c[i-1][j-1]+c[i-1][j]\)c[i-1][j-1]是新形成了这么多串,c[i-1][j]是继承之前已经形成了的串、

  但是一看样例,事情并不简单,有的字母重复出现,就会导致序列算重,因此要记录每个字母上一次出想的位置last。

  最终的方程是:

\[c[i][j]=c[i-1][j-1]+c[i-1][j]-c[last-1][j-1]
\]

  上代码:

#include<bits/stdc++.h>
using namespace std;
namespace STD
{
#define ll long long
#define rr register
const int SIZE=3001;
const int mod=998244353;
int l;
char s[SIZE];
int c[SIZE][SIZE];
int last[29];
int read()
{
rr int x_read=0,y_read=1;
rr char c_read=getchar();
while(c_read<'0'||c_read>'9')
{
if(c_read=='-') y_read=-1;
c_read=getchar();
}
while(c_read<='9'&&c_read>='0')
{
x_read=(x_read*10)+(c_read^48);
c_read=getchar();
}
return x_read*y_read;
}
};
using namespace STD;
int main()
{
int x=scanf("%s",s+1);
int len=strlen(s+1);
l=read();
c[1][1]=1;
for(rr int i=0;i<=len;i++) c[i][0]=1;
last[s[1]-'a'+1]=1;
for(rr int i=2;i<=len;i++)
{
for(rr int j=1;j<=l;j++)
{
if(j>i) break;
if(last[s[i]-'a'+1])
c[i][j]=((c[i-1][j]+c[i-1][j-1])%mod-c[last[s[i]-'a'+1]-1][j-1]+mod)%mod;
else
c[i][j]=(c[i-1][j]+c[i-1][j-1])%mod;
}
last[s[i]-'a'+1]=i;
}
printf("%d",c[len][l]);
}

NOIP模拟14「队长快跑·影魔·抛硬币」的更多相关文章

  1. NOIP 模拟 $14\; \text{队长快跑}$

    题解 \(by\;zj\varphi\) 一道很妙的 \(dp\) 题,方程状态不好设置,细节也不少 看到数据范围,直接想离散化 设 \(f_{i,j}\) 表示处理完前 \(i\) 个水晶,其中摧毁 ...

  2. HZOI20190908模拟40 队长快跑,影魔,抛硬币 题解

    题面:https://www.cnblogs.com/Juve/articles/11487699.html 队长快跑: 权值线段树与dp yy的不错 #include<iostream> ...

  3. [LOJ 2022]「AHOI / HNOI2017」队长快跑

    [LOJ 2022]「AHOI / HNOI2017」队长快跑 链接 链接 题解 不难看出,除了影响到起点和终点的射线以外,射线的角度没有意义,因为如果一定要从该射线的射出一侧过去,必然会撞到射线 因 ...

  4. Noip模拟14 2021.7.13

    T1 队长快跑 本身dp就不强的小马看到这题并未反映过来是个dp(可能是跟题面太过于像那个黑题的队长快跑相似) 总之,基础dp也没搞出来,不过这题倒是启发了小马以后考试要往dp哪里想想 $dp_{i, ...

  5. BZOJ4829: [Hnoi2017]队长快跑

    BZOJ4829: [Hnoi2017]队长快跑 Description 众所周知,在P国外不远处盘踞着巨龙大Y. 传说中,在远古时代,巨龙大Y将P国的镇国之宝窃走并藏在了其巢穴中,这吸引着整个P国的 ...

  6. [CSP-S模拟测试]:队长快跑(DP+离散化+线段树)

    题目背景 传说中,在远古时代,巨龙大$Y$将$P$国的镇国之宝窃走并藏在了其巢穴中,这吸引着整个$P$国的所有冒险家前去夺回,尤其是皇家卫士队的队长小$W$.在$P$国量子科技实验室的帮助下,队长小$ ...

  7. NOIP 模拟 $14\; \text{影魔}$

    题解 \(by\;\;zj\varphi\) 不是原题 一道(对我来说)很需要技巧的题 对于颜色数如何处理 离线,将子树转化为 \(dfs\) 序,但这种做法无法处理深度 我们按照深度加点(可以通过 ...

  8. NOIP模拟 14

    垃圾成绩,一点都不稳定. 如果把数组开小的分得到的话..总分还挺不错.. 那又能怪谁,都快NOIP了还犯这种傻逼错误 nc哥是要阿卡的节奏..真是太强了 某kyh也不知道偷了谁的rp,分高的一批 wd ...

  9. [NOIP模拟14]题解

    当垃圾已经成为一种常态233333 A.旋转子段 考场上的$n^2$手残少了20分,555  (主要是因为实在打不出来$n^3$的做法所以写不了对拍?ccc为什么考场上没有想起有reverse()这么 ...

随机推荐

  1. 大数据学习(06)——Ozone介绍

    前面几篇文章把Hadoop常用的模块都学习了,剩下一个新模块Ozone,截止到今天最新版本是0.5.0Beta,还没出正式版.好在官方网站有文档,还是中文版的,但是中文版资料没有翻译完整,我试着把它都 ...

  2. C语言复习(六)----typedef 的作用

    typedef的作用 重命名变量:typedef unsigned int Uint;//可以使用Uint代替unsigned int 定义新的数据类型 typedef struct Books{ c ...

  3. RHCE_DAY03

    shell函数 在shell环境中,将一些需要重复使用的操作,定义为公共的语句块,即可称为函数(给一堆命令取一个别名) 函数可以使脚本中的代码更加简洁,增强易读性,提高脚本的执行效率 #函数定义格式1 ...

  4. [TensorFow2.0]-MNIST手写数字识别

    本人人工智能初学者,现在在学习TensorFlow2.0,对一些学习内容做一下笔记.笔记中,有些内容理解可能较为肤浅.有偏差等,各位在阅读时如有发现问题,请评论或者邮箱(右侧边栏有邮箱地址)提醒. 若 ...

  5. SaToken学习笔记-01

    SaToken学习笔记-01 SaToken版本为1.18 如果有排版方面的错误,请查看:传送门 springboot集成 根据官网步骤maven导入依赖 <dependency> < ...

  6. Rancher v1.6.29 Docker单节点部署

    前言: Docker镜像中心,有两个版本的rancher(1.X),镜像名称为:rancher/server,而rancher(2.X)的镜像名称是rancher/rancher 去daocloud官 ...

  7. Java Swing 空布局

    Swing 空布局 试了盒布局,说实话不太会用,很多地方都没法更加的细节,又翻了翻资料,知道了还有一个空布局,一看,真不错,很适合我这种菜鸡 用坐标就可以完成界面的布局,不错 话不多说,直接代码 pa ...

  8. Android中Context解析

    Context概念 当我们访问当前应用的资源,启动一个新的activity的时候都需要提供Context. Context是一个抽象基类,我们通过它访问当前包的资源(getResources.getA ...

  9. JAVA垃圾回收分代处理思想

    原文链接:http://www.cnblogs.com/laoyangHJ/archive/2011/08/17/JVM.html JVM分代垃圾回收策略的基础概念 JVM分代垃圾回收策略的基础概念 ...

  10. etcd学习(7)-etcd中的线性一致性实现

    线性一致性 CAP 什么是CAP CAP的权衡 AP wihtout C CA without P CP without A 线性一致性 etcd中如何实现线性一致性 线性一致性写 线性一致性读 1. ...