zoukankan      html  css  js  c++  java
  • codeforces750E New Year and Old Subsequence 矩阵dp + 线段树

    题目传送门

    思路:

      先看一个大牛的题解

      题解里面对矩阵的构造已经写的很清楚了,其实就是因为在每个字符串都有固定的很多中状态,刚好可以用矩阵来表达,所以$(i,j)$这种状态可以通过两个相邻的矩阵的$min(i,k)+(k,j)$得到,取最小值即可,由于这是一个区间问题,所以用线段树来维护区间的矩阵运算,这个运算就是取min的过程。

      虽然这道原题被出在2019icpc南昌网络赛中了,但这个做法以前确实没有遇见过,开阔了思路。

      代码和博客里的其实几乎一样。

    #pragma GCC optimize (2)
    #pragma G++ optimize (2)
    #pragma comment(linker, "/STACK:102400000,102400000")
    #include<bits/stdc++.h>
    #include<unordered_map>
    #define rep(i,a,b) for(int i=a;i<=b;++i)
    #define dep(i,b,a) for(int i=b;i>=a;--i)
    #define clr(a,b) memset(a,b,sizeof(a))
    #define pb push_back
    #define pii pair<int,int >
    using namespace std;
    typedef long long ll;
    ll rd()
    {
        ll x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    const int maxn = 2e5+10;
    int n,m;
    char s[maxn];
    struct matrix{
        int a[5][5];
        matrix(){clr(a,0x3f);}
        matrix operator *(matrix x){
            matrix res;
            rep(i,0,4){
                rep(j,0,4){
                    rep(k,0,4){
                        res.a[i][j]=min(res.a[i][j],a[i][k]+x.a[k][j]);
                    }
                }
            }
            return res;
        }
    };
    struct Tree{
        int l,r;
        matrix M;
    }t[maxn<<2];
    void pushup(int x){
        t[x].M=t[x<<1].M*t[x<<1|1].M;
    }
    void build(int x,int l,int r){
        t[x].l=l,t[x].r=r;int mid=(l+r)>>1;
        if(l == r){
            for(int i = 0; i < 5; i++) t[x].M.a[i][i] = 0;
            if(s[l] == '2') t[x].M.a[0][0] = 1, t[x].M.a[0][1] = 0;
            if(s[l] == '0') t[x].M.a[1][1] = 1, t[x].M.a[1][2] = 0;
            if(s[l] == '1') t[x].M.a[2][2] = 1, t[x].M.a[2][3] = 0;
            if(s[l] == '7') t[x].M.a[3][3] = 1, t[x].M.a[3][4] = 0;
            if(s[l] == '6') t[x].M.a[3][3] = 1, t[x].M.a[4][4] = 1;
            return;
        }
        build(x<<1,l,mid),build(x<<1|1,mid+1,r);
        pushup(x);
    }
    matrix query(int x,int l,int r){
        if(l<=t[x].l&&t[x].r<=r)return t[x].M;
        int mid=(t[x].l+t[x].r)>>1;
        if(r<=mid)return query(x<<1,l,r);
        if(l>mid)return query(x<<1|1,l,r);
        return query(x<<1,l,r)*query(x<<1|1,l,r);
    }
    int main(){
        int x,y;
        cin>>n>>m>>(s+1);
        build(1,1,n);
        rep(i,1,m){
            scanf("%d%d",&x,&y);
            matrix ans=query(1,x,y);
            printf("%d
    ",ans.a[0][4]>n?-1:ans.a[0][4]);
        }
    }
  • 相关阅读:
    MySQL-07-新增数据
    MySQL-06-表结构修改
    LVM-创建与增容
    Zabbix-4.0.34-安装配置
    MySQL-05-约束
    lnmp(部署在一台上面)
    shell脚本概念和yum仓库的搭建
    awk命令基础和进阶
    shell
    awk
  • 原文地址:https://www.cnblogs.com/mountaink/p/11494079.html
Copyright © 2011-2022 走看看