zoukankan      html  css  js  c++  java
  • The 2019 Asia Nanchang First Round Online Programming Contest C(cf原题,线段树维护矩阵)

    题:https://nanti.jisuanke.com/t/41350

    分析:先将字符串转置过来

    状态转移,因为只有5个状态,所以 i 状态到 j 状态的最小代价就枚举【i】【k】->【k】【j】的最小值(0<=k<=4)

    0:初始状态
    1:2
    2:20
    3:201
    4:2019
    mat[i][j]表示状态i转移到j的最小代价
    #include<bits/stdc++.h>
    using namespace std;
    #define lson root<<1,l,midd
    #define rson root<<1|1,midd+1,r
    const int N=2e5+5;
    struct node{
        int mat[5][5];
        void init(){
            memset(mat,0x3f,sizeof(mat));
        }
        node operator + (const node &b){
            node ret;
            for(int i=0;i<5;i++)
                for(int j=0;j<5;j++){
                    ret.mat[i][j]=N;
                    for(int k=0;k<5;k++)
                        ret.mat[i][j]=min(ret.mat[i][j],mat[i][k]+b.mat[k][j]);
                }
            return ret;
        }
    }tree[N<<2],ANS;
    char s[N];
    void build(int root,int l,int r){
        if(l==r){
            for(int i=0;i<5;i++)
                for(int j=0;j<5;j++)
                    if(j!=i)
                        tree[root].mat[i][j]=N;
                    else
                        tree[root].mat[i][j]=0;
            if(s[l]=='8')
                tree[root].mat[4][4]=1,tree[root].mat[3][3]=1;
            else if(s[l]=='9')
                tree[root].mat[3][3]=1,tree[root].mat[3][4]=0;
            else if(s[l]=='1')
                tree[root].mat[2][2]=1,tree[root].mat[2][3]=0;
            else if(s[l]=='0')
                tree[root].mat[1][1]=1,tree[root].mat[1][2]=0;
            else if(s[l]=='2')
                tree[root].mat[0][0]=1,tree[root].mat[0][1]=0;
            return ;
        }
        int midd=(l+r)>>1;
        build(lson);
        build(rson);
        tree[root]=tree[root<<1]+tree[root<<1|1];
    }
    void query(int L,int R,int root,int l,int r){
        if(L<=l&&r<=R){
            ANS=ANS+tree[root];
            return ;
        }
        int midd=(l+r)>>1;
        if(L<=midd)
            query(L,R,lson);
        if(R>midd)
            query(L,R,rson);
        
    }
    char f[N];
    int main(){
        int n,t;
        scanf("%d%d",&n,&t);
        scanf("%s",f+1);
        for(int i=1,j=n;i<=n;i++,j--)
            s[i]=f[j];
    
        //cout<<endl;
        build(1,1,n);
        while(t--){
            int l,r;
            scanf("%d%d",&l,&r);
            int L=n-r+1,R=n-l+1;
            ANS.init();
            for(int i=0;i<5;i++)
                ANS.mat[i][i]=0;
            query(L,R,1,1,n);
            int ans=ANS.mat[0][4];
            if(ans==N)
                ans=-1;
            printf("%d
    ",ans); 
        }
        return 0;
        
    }
    View Code
  • 相关阅读:
    7.20 高博教育 方法
    7.20 高博教育 随机数字(练习)
    7.17 高博教育 流程控制02
    7月17号 高博教育 复习加逻辑运算符
    7月16号 高博教育 知识扩展
    7月16号 高博教育 知识点总结
    7月16号 高博教育 数据运算符和比较运算符
    链式线性表——课上练
    顺序线性表——课上练
    链栈——课上练
  • 原文地址:https://www.cnblogs.com/starve/p/11494775.html
Copyright © 2011-2022 走看看