埃森哲杯第十六届上海大学程序设计联赛春季赛暨上海高校金马五校赛H题小Y与多米诺骨牌(线段树优化dp)

原创 2018年04月17日 11:20:36

题意

题目链接:https://www.nowcoder.com/acm/contest/91/H
来源:牛客网

题解

l[i]为向左推第i个骨牌最远能影响到的骨牌的编号,r[i]为向右推第i个骨牌最远能影响到的骨牌的编号,则有:

l[i]=min(l[j])+1, (j<i,x[i]y[i]<x[j])r[i]=max(r[j])+1, (i<j,x[j]<x[i]+y[i])

使用线段树预处理出lr数组,复杂度为O(nlog(n))
dp[i][0]表示第i个骨牌向左倒时,让前i个骨牌全倒的最少要推的骨牌数;dp[i][1]表示第i个骨牌向右倒时,让前i个骨牌全倒的最少要推的骨牌数。则有:
dp[i][0]=min{dp[j1][0]+1,l[i]jdp[j1][1]+1,l[i]jdp[i][1]=min{dp[j1][0]+1,r[j]idp[i1][1]+1,r[j]i

答案就是min(dp[n][0],dp[n][1]),用线段树优化dp方程,复杂度为O(nlog(n))

代码

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define N 100010
#define lx x<<1
#define rx x<<1|1
#define lson x<<1,s,mid
#define rson x<<1|1,mid+1,t
const int inf=0x3f3f3f3f;
int n;
int seg[2][N*6],lazy[2][N*6];
int x[N],y[N],l[N],r[N],dp[2][N];
inline int op(int k,int x,int y)
{
    if(k==0) return min(x,y);
    else return max(x,y);
}
void build2(int x,int s,int t)
{
    seg[0][x]=s;seg[1][x]=t;
    if(s==t)
    {
        l[s]=r[s]=s;
        return;
    }
    int mid=s+t>>1;
    build2(lson);build2(rson);
}
void updata2(int k,int x,int s,int t,int id,int w)
{
    if(s==t){seg[k][x]=w;return;}
    int mid=s+t>>1;
    if(id<=mid) updata2(k,lson,id,w);
    else updata2(k,rson,id,w);
    seg[k][x]=op(k,seg[k][lx],seg[k][rx]);
}
int query2(int k,int x,int s,int t,int l,int r)
{
    if(l<=s&&t<=r) return seg[k][x];
    int mid=s+t>>1,q=(k?0:inf);
    if(l<=mid) q=op(k,q,query2(k,lson,l,r));
    if(mid<r) q=op(k,q,query2(k,rson,l,r));
    return q;
}
inline void pushdown(int k,int x,int s,int t)
{
    if(lazy[k][x]!=inf)
    {
        if(s!=t)
        {
            seg[k][lx]=min(seg[k][lx],lazy[k][x]);
            seg[k][rx]=min(seg[k][rx],lazy[k][x]);
            lazy[k][lx]=min(lazy[k][lx],lazy[k][x]);
            lazy[k][rx]=min(lazy[k][rx],lazy[k][x]);
        }
        lazy[k][x]=inf;
    }
}
void updata(int k,int x,int s,int t,int l,int r,int w)
{
    if(l<=s&&t<=r)
    {
        seg[k][x]=min(seg[k][x],w);
        lazy[k][x]=min(lazy[k][x],w);
        return;
    }
    pushdown(k,x,s,t);
    int mid=s+t>>1;
    if(l<=mid) updata(k,lson,l,r,w);
    if(mid<r) updata(k,rson,l,r,w);
    seg[k][x]=min(seg[k][lx],seg[k][rx]);
}
int query(int k,int x,int s,int t,int l,int r)
{
    if(l<=s&&t<=r) return seg[k][x];
    pushdown(k,x,s,t);
    int mid=s+t>>1,q=inf;
    if(l<=mid) q=min(q,query(k,lson,l,r));
    if(mid<r) q=min(q,query(k,rson,l,r));
    return q;
}
int main()
{
    int ca;
    scanf("%d",&ca);
    while(ca--)
    {
        scanf("%d",&n);
        for(int i=1;i<=n;++i)
            scanf("%d%d",&x[i],&y[i]);
        build2(1,0,n);
        for(int i=2;i<=n;++i)
        {
            int k=upper_bound(x+1,x+n+1,x[i]-y[i])-x;
            l[i]=query2(0,1,0,n,k,i);
            updata2(0,1,0,n,i,l[i]);
        }
        for(int i=n-1;i>0;--i)
        {
            int k=lower_bound(x+1,x+n+1,x[i]+y[i])-x-1;
            r[i]=query2(1,1,0,n,i,k);
            updata2(1,1,0,n,i,r[i]);
        }
        memset(seg,0x3f,sizeof(seg));
        memset(lazy,0x3f,sizeof(lazy));
        dp[0][0]=0;updata(0,1,0,n,0,0,0);
        dp[1][0]=0;updata(1,1,0,n,0,0,0);
        for(int i=1;i<=n;++i)
        {
            int tmp0=query(0,1,0,n,l[i]-1,i-1);
            int tmp1=query(1,1,0,n,l[i]-1,i-1);
            dp[0][i]=min(tmp0,tmp1)+1;
            updata(0,1,0,n,i,i,dp[0][i]);
            updata(1,1,0,n,i,r[i],min(dp[0][i-1],dp[1][i-1])+1);
            dp[1][i]=query(1,1,0,n,i,i);
        }
        printf("%d\n",min(dp[0][n],dp[1][n]));
    }
    return 0;
}
/*
3
4
1 3
2 1
3 1
4 3
3
1 3
4 2
5 2
3
1 3
4 3
7 7
*/

第15届上海大学程序设计联赛夏季赛暨上海高校金马五校赛(部分题解)

唉,好久没更新博客了,说明我这段时间在学习上都懈怠了Σ( ° △ °|||)︴昨天打了场金马赛,这网络…..我真的是无力吐槽…..前三题都是大水题,就不挂代码了;D-快速幂取模裸题#include u...
  • Murphyc
  • Murphyc
  • 2017-07-10 13:54:47
  • 482

埃森哲杯第十六届上海大学程序设计联赛春季赛暨上海高校金马五校赛

五题菜狗… 那个自习室真是有毒..坐了一下子马上就感冒了..头痛… A Wasserstein Distance 这题也是搞不懂,一开始狂wa,迷迷糊糊的. #include &amp;lt;...
  • m0_37802215
  • m0_37802215
  • 2018-04-15 20:09:09
  • 125

埃森哲杯第十六届上海大学程序设计联赛春季赛暨上海高校金马五校赛H题小Y与多米诺骨牌(线段树优化dp)

题意 题目链接:https://www.nowcoder.com/acm/contest/91/H 来源:牛客网 题解 设l[i]l[i]l[i]为向左推第iii个骨牌最远能影响到的骨牌的...
  • ME495
  • ME495
  • 2018-04-17 11:20:36
  • 86

【牛客网】【埃森哲杯第十六届上海大学程序设计联赛春季赛暨上海高校金马五校赛】L—K序列【动态规划】

题目链接:L—K序列题解:for一遍数组,temp[i]表示:不包括当前for到的点,序列和为i的最长长度。然后for一遍0-k,对dp[ (j+num[i])%k ]进行更新,dp[j]是包括当前点...
  • gymgym1212
  • gymgym1212
  • 2018-04-15 18:46:39
  • 165

【牛客网】【埃森哲杯第十六届上海大学程序设计联赛春季赛暨上海高校金马五校赛】B—合约数【莫队做法】

题目链接:B—合约数题意:一棵树,有n个节点,从1编号到n。根节点的编号为p。给出每个节点的val[i]值,定义f(i)为以编号i为根节点的子树中(包括根节点),所有val[j]是合数并且是val[i...
  • gymgym1212
  • gymgym1212
  • 2018-04-15 20:33:28
  • 133

埃森哲杯第十六届上海大学程序设计联赛春季赛暨上海高校金马五校赛F题 1+2=3?

题目链接:https://www.nowcoder.com/acm/contest/91/F题意:求第N个符合条件X^2X=3X的X。N&amp;lt;=10的12次方。解题思路:我刚开始想到最粗暴的...
  • weixin_36416680
  • weixin_36416680
  • 2018-04-16 11:01:00
  • 50

埃森哲杯第十六届上海大学程序设计联赛春季赛暨上海高校金马五校赛 F-1+2=3?

链接:https://www.nowcoder.com/acm/contest/91/F来源:牛客网题目描述 小Y在研究数字的时候,发现了一个神奇的等式方程,他屈指算了一下有很多正整数x满足这个等式...
  • albertluf
  • albertluf
  • 2018-04-15 16:46:44
  • 117

埃森哲杯第十六届上海大学程序设计联赛春季赛暨上海高校金马五校赛 J-小Y写文章(二分+二分图匹配)

链接:https://www.nowcoder.com/acm/contest/91/J来源:牛客网题目描述 小Y写了一篇文章,他对自己的文笔很有自信,尤其是自己总结出了一套计算文章通顺性的公式。 ...
  • albertluf
  • albertluf
  • 2018-04-18 10:27:07
  • 50

埃森哲杯第十六届上海大学程序设计联赛春季赛暨上海高校金马五校赛 L K序列

题目: 给一个数组 a,长度为 n,若某个子序列中的和为 K 的倍数,那么这个序列被称为“K 序列”。现在要你 对数组 a 求出最长的子序列的长度,满足这个序列是 K 序列。 Input: 第...
  • Tony5t4rk
  • Tony5t4rk
  • 2018-04-16 19:42:25
  • 10

K序列--埃森哲杯第十六届上海大学程序设计联赛春季赛暨上海高校金马五校赛

链接:https://www.nowcoder.com/acm/contest/91/L来源:牛客网K序列时间限制:C/C++ 1秒,其他语言2秒空间限制:C/C++ 131072K,其他语言2621...
  • zitian246
  • zitian246
  • 2018-04-16 16:47:40
  • 40
收藏助手
不良信息举报
您举报文章:埃森哲杯第十六届上海大学程序设计联赛春季赛暨上海高校金马五校赛H题小Y与多米诺骨牌(线段树优化dp)
举报原因:
原因补充:

(最多只允许输入30个字)