真的是下定了巨大的决心来搞这一讲,果不其然耗了一晚上

开车旅行(真的是NOIP的题吗怎么这么恐怖)

首先,先用set把小A和小B从城市i出发,到达的下一个城市预处理出来。

f[i][j][k]表示走了2^i天,j城市出发,k表示谁开车,到达那个城市。

转移就是f[i][j][k]=f[i-1][f[i-1][j][k]][k] 相信很好理解

特别的i-1==0时,因为k是奇数,开车的人是变化的,所以f[i][j][k]=f[i-1][f[i-1][j][k]][k^1]

令da[i][j][k],db[i][j][k],分别表示小A和小B这个状态下走的路程

对于询问1,枚举所有的城市作为起点,然后基于二进制划分的思想,倒着for一步步在满足走的总路程<=x0的情况下前进,这样可以计算出小A走的路程和小B走的路程。找最大比值即可。

询问二就直接询问小A走的路程和小B走的路程了。同理可求。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<set>
using namespace std;
typedef long long LL; int h[];
struct snode
{
int id,h;
snode(){}
snode(int ID,int H){id=ID;h=H;}
friend bool operator <(snode s1,snode s2){return s1.h<s2.h;}
};
set<snode>S;
set<snode>::iterator it,lt,rt;
int g[],I;
bool cmp(int g1,int g2){return (abs(h[g1]-h[I])<abs(h[g2]-h[I]))||(abs(h[g1]-h[I])==abs(h[g2]-h[I])&&h[g1]<h[g2]);} int Ago[],Bgo[];
int f[][][]; LL da[][][],db[][][]; LL A,B;
void solve(int now,int x0)
{
A=B=; int k=;
for(int i=;i>=;i--)
if(f[i][now][k]!=&&da[i][now][k]+db[i][now][k]<=x0)
{
x0-=da[i][now][k]+db[i][now][k];
A+=da[i][now][k],B+=db[i][now][k];
if(i==)k^=;
now=f[i][now][k];
}
} int main()
{
int n;
scanf("%d",&n);
for(int i=;i<=n;i++)scanf("%d",&h[i]);
memset(Ago,,sizeof(Ago));
memset(Bgo,,sizeof(Bgo));
for(int i=n;i>=;i--)
{
S.insert(snode(i,h[i]));
it=lt=rt=S.find(snode(i,h[i]));
int m=;
if(lt!=S.begin())
{
lt--,g[++m]=(*lt).id;
if(lt!=S.begin())lt--,g[++m]=(*lt).id;
}
rt++;
if(rt!=S.end())
{
g[++m]=(*rt).id;
rt++;if(rt!=S.end())g[++m]=(*rt).id;
}
I=i;sort(g+,g+m+,cmp);
if(m>)Ago[i]=g[];
if(m>)Bgo[i]=g[];
} memset(f,,sizeof(f));
for(int i=;i<=n;i++)
{
if(Ago[i]!=) f[][i][]=Ago[i], da[][i][]=abs(h[Ago[i]]-h[i]), db[][i][]=;
if(Bgo[i]!=) f[][i][]=Bgo[i], da[][i][]=, db[][i][]=abs(h[Bgo[i]]-h[i]);
}
for(int i=;i<=;i++)
for(int j=;j<=n;j++)
for(int k=;k<=;k++)
{
int l=k;if(i==)l=k^; if(f[i-][j][k]>)f[i][j][k]=f[i-][f[i-][j][k]][l];
if(f[i][j][k]>)
{
da[i][j][k]=da[i-][j][k]+da[i-][f[i-][j][k]][l];
db[i][j][k]=db[i-][j][k]+db[i-][f[i-][j][k]][l];
}
} int x0,ans;LL ansA=,ansB=;
scanf("%d",&x0);
for(int i=;i<=n;i++)
{
solve(i,x0); if(B==)A=;
if(A*ansB<ansA*B||(A*ansB==ansA*B&&h[i]>h[ans]))ansA=A,ansB=B,ans=i;
}
printf("%d\n",ans); int Q,x,y;
scanf("%d",&Q);
while(Q--)
{
scanf("%d%d",&x,&y);
solve(x,y);
printf("%lld %lld\n",A,B);
} return ;
}

开车旅行

Count The Repetitions

f[j][i]表示从s1第i个字符开始,能够表示出s2 2^j最少需要多少字符。

就有f[j][i]=f[j-1][i]+f[j-1][((i+f[j-1][i])-1)%s1len+1]

最后就枚举匹配的起始点,同样在不超过s1len*n1的情况下用二进制一步步跳,记录当前起始点的最优解更新答案就好了。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long LL; char s1[],s2[];
LL f[][];
int main()
{
freopen("2.in","r",stdin);
freopen("2.out","w",stdout);
while()
{
int n2,n1;
scanf("%s",s2+);if(s2[]=='}')break;
scanf("%d%s%d",&n2,s1+,&n1);
int s2len=strlen(s2+),s1len=strlen(s1+); bool bk=false;
for(int i=;i<=s1len;i++)
{
int p=i;f[][i]=;
for(int j=;j<=s2len;j++)
{
int cc=;
while(s1[p]!=s2[j])
{
p=p%s1len+;
cc++;if(cc>=s1len){printf("0\n");bk=true;break;}
}
p=p%s1len+;
f[][i]+=cc+;
if(bk==true)break;
}
if(bk==true)break;
}
if(bk==true)continue; for(int j=;j<=;j++)
for(int i=;i<=s1len;i++)
f[j][i]=f[j-][i]+f[j-][((i+f[j-][i])-)%s1len+]; LL m=;
for(int i=;i<=s1len;i++)
{
int x=i;LL ans=;
for(int j=;j>=;j--)
if(x+f[j][(x-)%s1len+]-<=s1len*n1)
x+=f[j][(x-)%s1len+], ans+=(<<j);
m=max(m,ans);
}
printf("%lld\n",m/n2);
}
return ;
}

Count The Repetitions

好像都是先预处理出下一步的状态,然后二进制划分啊

0x57 倍增优化DP的更多相关文章

  1. HZOJ 20190727 随(倍增优化dp)

    达哥T1 实际上还是挺难的,考试时只qj20pts,还qj失败 因为他专门给出了mod的范围,所以我们考虑把mod加入时间复杂度. $50\%$算法: 考虑最暴力的dp,设$f[i][j]$表示进行$ ...

  2. $Noip2012\ Luogu1081$ 开车旅行 倍增优化$ DP$

    Luogu Description Sol 1.发现对于每个城市,小A和小B的选择是固定的,可以预处理出来,分别记为ga[],gb[] 2.并且,只要知道了出发城市和出发天数,那么当前城市和小A,小B ...

  3. CodeForces - 1175E Minimal Segment Cover (倍增优化dp)

    题意:给你n条线段[l,r]以及m组询问,每组询问给出一组[l,r],问至少需要取多少个线段可以覆盖[l,r]区间中所有的点. 如果贪心地做的话,可以求出“从每个左端点l出发选一条线段可以到达的最右端 ...

  4. $CH0601\ Genius\ ACM$ 倍增优化DP

    ACWing Description 给定一个长度为N的数列A以及一个整数T.我们要把A分成若干段,使得每一段的'校验值'都不超过N.求最少需要分成几段. Sol 首先是校验值的求法: 要使得'每对数 ...

  5. POJ 1014 Dividing(多重背包, 倍增优化)

    Q: 倍增优化后, 还是有重复的元素, 怎么办 A: 假定重复的元素比较少, 不用考虑 Description Marsha and Bill own a collection of marbles. ...

  6. Codeforces 356D 倍增优化背包

    题目链接:http://codeforces.com/contest/356/problem/D 思路(官方题解):http://codeforces.com/blog/entry/9210 此题需要 ...

  7. 矩阵乘法优化DP复习

    前言 最近做毒瘤做多了--联赛难度的东西也该复习复习了. Warning:本文较长,难度分界线在"中场休息"部分,如果只想看普及难度的可以从第五部分直接到注意事项qwq 文中用(比 ...

  8. bzoj-4518 4518: [Sdoi2016]征途(斜率优化dp)

    题目链接: 4518: [Sdoi2016]征途 Description Pine开始了从S地到T地的征途. 从S地到T地的路可以划分成n段,相邻两段路的分界点设有休息站. Pine计划用m天到达T地 ...

  9. bzoj-1096 1096: [ZJOI2007]仓库建设(斜率优化dp)

    题目链接: 1096: [ZJOI2007]仓库建设 Description L公司有N个工厂,由高到底分布在一座山上.如图所示,工厂1在山顶,工厂N在山脚.由于这座山处于高原内陆地区(干燥少雨),L ...

随机推荐

  1. Spring Boot (4) 静态页面和Thymeleaf模板

    静态页面 spring boot项目只有src目录,没有webapp目录,会将静态访问(html/图片等)映射到其自动配置的静态目录,如下 /static /public /resources /ME ...

  2. Oracle 中文排序

        按照拼音顺序(常用)     ORDER BY nlssort(NAME, 'NLS_SORT=SCHINESE_PINYIN_M') 按照部首顺序 ORDER BY nlssort(NAME ...

  3. SQLServer2008 去除换行符

    declare @str varchar(8000)set @str='SQL语句' select replace(@str,char(10),'')

  4. SQL server高级语法

    1. 公共表达式CTE 公用表表达式 (CTE) 具有一个重要的优点,那就是能够引用其自身,从而创建递归 CTE.递归 CTE 是一个重复执行初始 CTE 以返回数据子集直到获取完整结果集的公用表表达 ...

  5. 【转】虚拟化(三):vsphere套件的安装注意及使用

    vsphere套件里面主要的组件有esxi.vcenter server .vsphere client和vsphere web client. vcenter做为vsphere套件的核心管理成员之一 ...

  6. Android LinearLayout整个布局设置不可点击

    1,activity的xml布局(布局中有个Button按钮,点击按钮弹出一个popupwindow ) <?xml version="1.0" encoding=" ...

  7. 数据库Day3之SQL Server 触发器

    最近在做一个人事管理系统写了几个简单的触发器 1.在删除员工信息表中员工信息时结果区提示被删除员工信息 create trigger teston 员工信息表after deleteasselect ...

  8. MessageFormat.format()用法

    1.java.text.Format的继承结构如下   2.MessageFormat模式 FormatElement { ArgumentIndex }:是从0开始的入参位置索引 { Argumen ...

  9. 使用Arcgis进行画面(线)并计算大小(长度)。

    在使用Arcgis API for JavaScript进行做地图开发的过程中,在地图进行画线.画面是经常使用的功能.本文主要介绍这一功能. 本文适用Arcgis API版本:Arcgis API f ...

  10. Centos 7源码编译搭建Nginx

    一.Nginx入门介绍 1. Nginx(engine x):[ˈendʒɪnks] 2. Nginx 是 Igor Sysoev 为俄罗斯访问量第二的 Rambler.ru 站点开发的,第一个公开版 ...