zoukankan      html  css  js  c++  java
  • FZU 2041 二分枚举

    思路:先O(n)预处理出ri[i][j],le[i][j],分别表示第i个位置向右边移动出j个空格需要的步数,表示第i个位置向左边移动出j个空格需要的步数。

    然后枚举间隙处,二分判段最大间隔。

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #define Maxn 710
    #define inf 100000000
    using namespace std;
    int ri[Maxn][Maxn],le[Maxn][Maxn],n,m;
    char str[Maxn];
    bool OK(int pos,int x)
    {
        int i,j,cnt=inf;
        if(pos==1) {
            cnt=min(cnt,ri[pos][x]);
            return cnt<=m;
        }
        for(i=0;i<=n;i++){
            if(i>x) break;
            cnt=min(cnt,ri[pos][i]+le[pos-1][x-i]);
        }
        //cout<<pos<<" "<<x<<" "<<cnt<<" "<<m<<endl;
        return cnt<=m;
    }
    int main()
    {
        int t,i,j,ze,Ca=0;
        scanf("%d",&t);
        while(t--){
            for(i=1;i<Maxn;i++){
                for(j=1;j<Maxn;j++){
                    ri[i][j]=le[i][j]=inf;
                }
            }
            ze=0;
            scanf("%d%d%s",&n,&m,str);
            if(str[0]=='0') le[1][1]=0,ze=1;
            for(i=1;i<n;i++){
                if(str[i]=='0') ze++;
                for(j=1;j<=n;j++){
                    if(le[i][j-1]>=inf) break;
                    if(str[i]=='1')
                        le[i+1][j]=le[i][j]+j;
                    else
                        le[i+1][j]=le[i][j-1];
                }
            }
            if(str[n-1]=='0') ri[n][1]=ri[n+1][1]=0;
            for(i=n-1;i>=1;i--){
                for(j=1;j<=n;j++){
                    if(ri[i+1][j-1]>=inf) break;
                    if(str[i-1]=='1')
                        ri[i][j]=ri[i+1][j]+j;
                    else
                        ri[i][j]=ri[i+1][j-1];
                }
            }
            int f=0;
            int ans=0,l,r,mid;
            for(i=1;i<=n;i++){
                if(str[i-1]=='0'){
                    l=0;r=ze;
                    while(l+1<r){
                        mid=(l+r)>>1;
                        if(OK(i,mid))
                            l=mid;
                        else
                            r=mid;
                    }
                    ans=max(ans,l);
                    if(OK(i,r))
                        ans=max(ans,r);
                }
            }
            printf("Case %d: %d
    ",++Ca,ans);
        }
        return 0;
    }
  • 相关阅读:
    拥有最多糖果的孩子
    求1+2+…+n
    网络-中间代理
    Header中的Referer属性表示
    ios13.4post请求出现网错错误 network err
    10.8&10.10
    9.23&9.27
    9.16&9.19
    校内模拟赛划水报告(9.9,9.11)
    男人八题 划水题解
  • 原文地址:https://www.cnblogs.com/wangfang20/p/3353668.html
Copyright © 2011-2022 走看看