zoukankan      html  css  js  c++  java
  • Codeforces Round #587 (Div. 3) F Wi-Fi(线段树+dp)

     题意:给定一个字符串s 现在让你用最小的花费 覆盖所有区间

    思路:dp[i]表示前i个全覆盖以后的花费 如果是0 我们只能直接加上当前位置的权值 否则 我们可以区间询问一下最小值 然后更新

    #include <bits/stdc++.h>
    using namespace std;
    const int inf = 0x3f3f3f3f;
    const double eps = 1e-6;
    const int N = 2e5+7;
    typedef long long ll;
    const ll mod = 998244353;
    using namespace std;
    ll dp[N];
    ll a[N],sum[N];
    struct tree{
        int l,r;
        ll v;
        int po;
    }t[N<<4];
    int nico=0;
    void build(int p,int l,int r){
        t[p].l=l; t[p].r=r; t[p].v=inf;
        if(l==r){
            t[p].po=l;
            return ;
        }
        int mid=(l+r)>>1;
        build(p<<1,l,mid);
        build(p<<1|1,mid+1,r);
    }
    void update(int p,int x,ll v){
        if(t[p].l==t[p].r){
            t[p].v=v;
            return ;
        }
        int mid=(t[p].l+t[p].r)>>1;
        if(x<=mid) update(p<<1,x,v);
        else update(p<<1|1,x,v);
        if(t[p<<1].v<t[p<<1|1].v){
            t[p].v=t[p<<1].v;
            t[p].po=t[p<<1].po;
        }else{
            t[p].v=t[p<<1|1].v;
            t[p].po=t[p<<1|1].po;
        }
    }
    tree query(int p,int l,int r){
        if(l<=t[p].l&&t[p].r<=r){
            return t[p];
        }
        int mid=(t[p].l+t[p].r)>>1;
        tree res1,res2;
        if(l>mid){
            return query(p<<1|1,l,r);
        }else if(r<=mid){
            return query(p<<1,l,r);
        }else{
            res1=query(p<<1,l,r);
            res2=query(p<<1|1,l,r);
            if(res1.v<res2.v){
                return res1;
            }else{
                return res2;
            }
        }
    }
    int main(){
        ios::sync_with_stdio(false);
        cin.tie(0); cout.tie(0);
        int n,k; cin>>n>>k;
        string s; cin>>s;
        build(1,0,n);
        update(1,0,0);
        for(int i=1;i<=n;i++){
            sum[i]=sum[i-1]+i;    
        }
        int mi=inf;
        for(int i=n-1;i>=0;i--){
            if(s[i]=='1'&&i!=n-1){
                s[min(i+k,n-1)]='1';
                s[i]='0';
                if(i+k>=n-1){
                    mi=min(mi,i)+1;
                }
            }
        }
        if(s[n-1]=='1'&&mi==inf){
            mi=n;
        }
    //    cout<<s<<endl;
        for(int i=1;i<=n;i++){
            if(s[i-1]=='1'){
                if(i==n){
                    tree res=query(1,max(mi-k-1,0),i-1);
                    dp[i]=res.v+mi;
                //    dp[i][0]=min(dp[i-1][0],dp[i-1][1])+mi;
                }else{
                    tree res=query(1,max(i-2*k-1,0),i-1);
                    dp[i]=res.v+i-k;
                //    dp[i][0]=min(dp[i-1][0],dp[i-1][1])+i-k;
                }
            }else{
                dp[i]=dp[i-1]+i;
            //    dp[i][0]=inf;
            }
            update(1,i,dp[i]);
        }
        cout<<dp[n]<<endl;
        return 0;
    }
    View Code
  • 相关阅读:
    寒假学习日报20
    寒假学习日报19
    Centos firewalld开放端口
    Full GC回收详解
    JVM调优6大步骤
    JVM的方法区和永久带是什么关系?
    sql优化的几种方式
    sentinel-dashboard安装、运行(ubuntu)
    RocketMQ工作原理
    linux:nohup 不生成 nohup.out的方法
  • 原文地址:https://www.cnblogs.com/wmj6/p/11568601.html
Copyright © 2011-2022 走看看