zoukankan      html  css  js  c++  java
  • The 2019 Asia Nanchang First Round Online Programming Contest C. Hello 2019(动态dp)

    题意:要找到一个字符串里面存在子序列9102 而不存在8102 输出最小修改次数

    思路:对于单次询问 我们可以直接区间dpOn求出最小修改次数 但是对于多次询问 我在大部分题解看到的解释一般是用线段树维护每一个区间段 每一个区间上挂一个dp[5][5]的矩阵 表示从i状态转移到j状态索要的最小修改次数 转移的时候就可以像区间dp一样 通过两个子区间合并 跟新答案。

    #include <bits/stdc++.h>
    using namespace std;
    const double pi = acos(-1.0);
    const int N = 2e5+7;
    const int inf = 0x3f3f3f3f;
    const double eps = 1e-6;
    typedef long long ll;
    const ll mod = 10007;
    char s[N];
    struct tree{
        int dp[5][5];
    }t[N<<2];
    int L[N<<2],R[N<<2];
    tree mul(tree a,tree b){
        tree tmp;
        memset(tmp.dp,inf,sizeof(tmp.dp));
        for(int i=0;i<5;i++)
            for(int j=0;j<5;j++)
                for(int k=0;k<5;k++)
                    tmp.dp[i][j]=min(tmp.dp[i][j],a.dp[i][k]+b.dp[k][j]);
        return tmp;
    }
    void build(int p,int l,int r){
        L[p]=l; R[p]=r;
    //    memset(t[p].dp,inf,sizeof(t[p].dp));
        if(l==r){
            memset(t[p].dp,inf,sizeof(t[p].dp));
            for(int i=0;i<5;i++) t[p].dp[i][i]=0;
            if(s[l]=='2'){
                t[p].dp[0][0]=1; t[p].dp[0][1]=0;
            }else if(s[l]=='0'){
                t[p].dp[1][1]=1; t[p].dp[1][2]=0;
            }else if(s[l]=='1'){
                t[p].dp[2][2]=1; t[p].dp[2][3]=0;
            }else if(s[l]=='9'){
                t[p].dp[3][3]=1; t[p].dp[3][4]=0;
            }else if(s[l]=='8'){
                t[p].dp[3][3]=1; t[p].dp[4][4]=1;
            }
            return ;
        }
        int mid=(l+r)>>1;
        build(p<<1,l,mid);
        build(p<<1|1,mid+1,r);
        t[p]=mul(t[p<<1],t[p<<1|1]);
    }
    tree query(int p,int l,int r){
        if(l<=L[p]&&R[p]<=r){
            return t[p];
        }
        int mid=(L[p]+R[p])>>1;
        tree ans1,ans2;
        memset(ans1.dp,inf,sizeof(ans1.dp));
        memset(ans2.dp,inf,sizeof(ans2.dp));
        if(r<=mid) return query(p<<1,l,r);
        if(l>mid) return query(p<<1|1,l,r);
        return mul(query(p<<1,l,r),query(p<<1|1,l,r));
    }
    int main(){
    //    ios::sync_with_stdio(false);
    //    cin.tie(0); cout.tie(0);
        int n,Q; scanf("%d%d",&n,&Q);
        scanf("%s",s+1);
        reverse(s+1,s+1+n);
    //    printf("%s
    ",s+1);
        build(1,1,n);
    //    cout<<t[1].dp[0][4]<<endl;
        for(int i=1;i<=Q;i++){
            int l,r; scanf("%d%d",&l,&r);
    //        cout<<n-r+1<<" "<<n-l+1<<endl;
            tree ans=query(1,n-r+1,n-l+1);
            printf("%d
    ",ans.dp[0][4]==inf?-1:ans.dp[0][4]);
        }
    }
    View Code
  • 相关阅读:
    编写安全有效的 C# 代码
    模式匹配
    C#新特性
    转 C# .NET4.0 混合模式程序集异常
    win7 64位系统 注册 ocx控件
    TIFF图像文件格式详解
    GDALOGR读取数据示例 C#版本
    使用gdal C#封装库读取DEM数据
    编译C#环境下GDAL(支持HDF4、NetCDF)
    UML类图符号 各种关系说明以及举例
  • 原文地址:https://www.cnblogs.com/wmj6/p/11495421.html
Copyright © 2011-2022 走看看