• CF1415C Bouncing Ball 题解


    题意分析

    给出一个由 $0,1$ 组成的序列,要从第 $p$ 个位置开始,每次跳 $k$ 个单位,要求跳出序列,只有当所有经过的位置都为 $1$ 才合法。你可以花费 $x$ 将这个序列的第一个元素删除,也可以花费 $y$ 将其中一个位置改为 $1$ ,求能合法跳出序列的最小修改花费。

    思路分析

    发现当第一个位置确定后,后面的所有跳到的位置都可以确定,考虑枚举删去的元素数量,即起始位置。

    显然前 $p-1$ 个元素都是无用的,可以不管它们,然后设为从第 $1$ 个位置开始。

    假设删去前 $i$ 个元素,那么很容易可以得出需要跳的次数:$left lceil frac{(n-i)}{k} ight ceil$ 。然后需要知道被跳到的地方有多少个位置为 $0$ ,这个可以把整个序列按照对 $k$ 的模数进行分类,然后对于每一类预处理出为 $1$ 的个数,处理的时候再统计当前位置之前的 $1$ 的个数,就可以得出后面的 $0$ 的个数。最后加上删去 $i$ 个元素的花费即可。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<cmath> 
    using namespace std;
    const int N=1e5+100;
    int T,n,p,k,x,y,ans;
    int cnt[N],ncnt[N];
    string s;
    void clear()
    {
        memset(cnt,0,sizeof(cnt));//整个序列中 1 的个数
        memset(ncnt,0,sizeof(ncnt));//当前位置之前的 1 的个数
        ans=1e9;
    }
    int main()
    {
        scanf("%d",&T);
        while(T--)
        {
            clear();
            scanf("%d%d%d",&n,&p,&k);cin>>s;scanf("%d%d",&x,&y);
            for(int i=p-1;i<n;i++)
                cnt[(i-p+1)%k]+=s[i]-'0';//预处理 1 的个数
            for(int i=p-1;i<n;i++)
                ans=min(ans,((int)ceil((double)(n-i)/k)-cnt[(i-p+1)%k]+ncnt[(i-p+1)%k])*x+(i-p+1)*y),ncnt[(i-p+1)%k]+=s[i]-'0';
            printf("%d
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    Python--my first try!
    AB PLC首次IP地址如何分配
    如何解压DMK固件
    罗克韦尔自动化官网如何下载设备固件
    如何使用AB PLC仿真软件Studio 5000 Logix Emulate
    Studio 5000指令IN_OUT管脚实现西门子风格
    AB PLC分类
    罗克韦尔自动化发展简史
    C#曲线分析平台的制作(五,Sqldependency+Signalr+windows 服务 学习资料总结)
    自动化监控上位机系统二次开发之我见
  • 原文地址:https://www.cnblogs.com/TEoS/p/14084101.html
Copyright © 2020-2023  润新知