• [CF587-F]WI-FI


    显然DP题...

    f[i][0]表示这个点不装路由器,f[i][1]表示装路由器

    转移也很简单,在前面一段区间找最小值就好了

    但是直接转移是$O(n*k)$的,会T掉

    大佬说这个东西有单调性,但是菜鸡我找不到,因为是区间问题,所以线段树强上

    区间查询+单点修改

     1 #include<bits/stdc++.h>
     2 #define int long long
     3 #define inf (0x7f7f7f7f7f7f7f)
     4 using namespace std;
     5 inline int read(){
     6     int ans=0,f=1;char chr=getchar();
     7     while(!isdigit(chr)){if(chr=='-') f=-1;chr=getchar();}
     8     while(isdigit(chr)){ans=(ans<<3)+(ans<<1)+chr-48;chr=getchar();}
     9     return ans*f;
    10 }const int M = 2e5+5;
    11 struct Segment_Tree{
    12     int s[M<<2];
    13     #define mid (l+r>>1)
    14     #define ls (i<<1)
    15     #define rs (i<<1|1)
    16     inline void Push_Up(int i){s[i]=min(s[ls],s[rs]);}
    17     void Build(int i,int l,int r){
    18         if(l==r)return (void)(s[i]=inf);
    19         Build(ls,l,mid),Build(rs,mid+1,r);
    20         Push_Up(i);
    21     }void Update(int i,int l,int r,int pos,int x){
    22         if(l==r)return (void)(s[i]=min(s[i],x));
    23         if(pos<=mid) Update(ls,l,mid,pos,x);
    24         else Update(rs,mid+1,r,pos,x);
    25         Push_Up(i);
    26     }int Query(int i,int l,int r,int ql,int qr){
    27         if(ql<=l&&r<=qr)return s[i];
    28         int t1=inf,t2=inf;
    29         if(ql<=mid) t1=Query(ls,l,mid,ql,qr);
    30         if(qr>mid)  t2=Query(rs,mid+1,r,ql,qr);
    31         return min(t1,t2);
    32     }
    33 }T1,T2;
    34 char s[M];
    35 int n,m,k,f[M][2];
    36 signed main(){
    37     n=read(),k=read();
    38     scanf("%s",s+2);
    39     T1.Build(1,1,n),T2.Build(1,1,n);
    40     memset(f,0x3f,sizeof(f));
    41     T2.Update(1,1,n,1,f[1][0]=f[1][1]=0);
    42     for(int i=2;i<=n+1;i++){
    43         f[i][0]=T1.Query(1,1,n,max(i-k,1ll),i-1);
    44         if(s[i]=='1') f[i][1]=T2.Query(1,1,n,max(1ll,i-k-1),i-1)+i-1;
    45         else f[i][1]=min(T1.Query(1,1,n,max(1ll,i-k-1),i-1),min(f[i-1][0],f[i-1][1]))+i-1;
    46         T2.Update(1,1,n,i,min(f[i][0],f[i][1]));
    47         if(s[i]=='1') T1.Update(1,1,n,i,f[i][1]);
    48     }cout<<min(f[n+1][0],f[n+1][1]);
    49     return 0;
    50 }
  • 相关阅读:
    前端验证银行卡(Luhn校验算法)
    常见的三狼布局
    项目中的分页插件
    JavaScript葵花宝典之闭包
    CSS 高级布局技巧
    window.open打开新窗口被浏览器拦截的处理方法
    Input输入框输入银行卡号自动空格
    关于NSURLSession的上传和下载
    将一个字符串从第40个字节开始替换为@"..."
    IOS开发之高级功能---远程推送
  • 原文地址:https://www.cnblogs.com/zhenglw/p/11567839.html
Copyright © 2020-2023  润新知