机房测试2:sushi(断环+贪心)

题目:

分析:

因为原序列是一个环,所以要断环为链,将序列复制一份放在后面。

显然将R移动到一块的同时,B也会在一块,所以只需要求R移动到一起的贡献即可。

枚举一个分界点,让这个点左边所有的R都向左靠,右边所有的R都向右靠。这时候一定是满足题意的。

但会发现,同一个分界点,随着断环的位置改变,统计出来的答案也会改变,所以还要枚举一个断环点

复杂度是n^2

考虑优化:

RRBBRBBBR 像这样一组数据,把将R向两边放看做是将B往中间靠,那么在第5个位置是最优的(左边移两格,右边不需要移)。

当断环的点向右移,lr不会增加,rr不会减少,相当于如果分界点向左移动,只会给右边带来更多的花费,也不会给左边减少花费(因为移动的是最左边的点)。

所以断环的点不会从原来的位置向左移动。

显然我们不需要将分界点从头枚举到尾,我们只需要找到一个最大的位置,当答案不再减小,就break掉(也就是说答案随分界点的变化是单调的)。

复杂度:接近O(n)

实现流程:

定义lr为左边R的个数,rr为右边R的个数,r为当前所需花费。枚举断环点,枚举分界点,统计答案。

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define N 1000005
#define ri register int
char s[N<<1];
void work()
{
    int n=strlen(s+1);
    for(ri i=1;i<=n;++i) s[i+n]=s[i];
    //断点指断环的点 分界点指不移动的点 将所有的B往中间分界点靠 R向两边靠
    int lr=0,rr=0;
    ll r=0,ans;
    for(ri i=1;i<=n;++i) if(s[i]==‘R‘) r+=n-i-rr,rr++;//预处理断点在1的情况
    //printf("%lld\n",rr);
    ans=r;
    int now=1;
    for(ri pos=1;pos<=n;++pos){//移动断点
        while(now<n+pos){//枚举分界点 跳指针移动
            if(s[now]==‘R‘){//移动B不影响 移动R会对lr 与 rr的统计有影响
                ll tmp=r;
                rr--;//移到了一个R 所以先右边的-- 减去它自己 便于下面统计 注意分界点这个点是包括在右区间里面的
                tmp+=now-pos-lr-(pos+n-1-now-rr);//pos是它目前的起点 pos+n-1是目前的终点
                //统计步数:这个R本来有移到右边的贡献 现在减去 加上移到左边的贡献
                lr++;//左边的++ 便于上面的统计
                if(tmp<=r) r=tmp;//如果不能更新 就还原 然后break
                else{ lr--; rr++; break; }
            }
            now++;
        }
        ans=min(ans,r);
        if(s[pos]==‘R‘) lr--,rr++;//如果把R移过去了 右边的R++ 左边--
        else r+=rr-lr;//如果移动的是B 就要加上所有右边的R移动到右边的贡献 减去左边的R移动到左边的贡献
    }
    printf("%lld\n",ans);
}
int main()
{
    freopen("sushi.in","r",stdin);
    freopen("sushi.out","w",stdout);
    int T;
    scanf("%d",&T);
    while(T--){
        scanf("%s",s+1);
        work();
    }
}
/*
1
BBRBBRBBBRRR
*/

原文地址:https://www.cnblogs.com/mowanying/p/11622618.html

时间: 2024-10-10 14:36:33

机房测试2:sushi(断环+贪心)的相关文章

机房测试:lunch(贪心+最短路)

题目: 分析: 由数据3得:既然所有人都要学会,肯定是越早学越优.(贪心重要思路) 所以转移就是:dis[v]=max( dis[u] ,L ),u学会之后传授给v的条件是:u先学会,传授的时间在吃饭的时间内 在最短路上转移即可 再考虑有人必须学不会的限制. 如果有一个人u没有学会,就会给他周围的人v一个限制:v不能太早学会,否则吃饭的时候v就会传授给u 所以将lim[v]定为L+1,即他们在L的时候吃饭,L+1的时候v才学会,不会传给u 先将这种传递关系用spfa预处理 再跑一边dij求出每个

机房测试1:big(贪心+Trie树)

题目: 分析: 考虑最暴力的办法:枚举选哪个数,枚举对手在哪个时间变化,然后统计答案. 对于异或这一类问题,考虑区间异或可以抵消重复区间,维护一个前缀异或和:pre[i]表示1~i的异或和,suf[i]表示i~n的异或和. 将对手的式子化简,2*x即将x向左移一位,/( 2^n )为向右移n位,+2*x ,%2^n类似. 模拟一下:12345 -> 123450 -> 123451 -> 23451 每次枚举对手要变的时间i,最后的值即为:work ( pre[i] ^ x ) ^ su

机房测试3:C++锦标赛(贪心)

题目: 分析: 首先理解题意:zyg要和每一个人都打比赛,且只有输和赢两种情况,也就是说没打赢的人最后得分要++. 我们希望zyg打赢的人尽量地少,且rp值小. 先对比分大小排序,估计一下对应排名的最小分数sc,再按rp从小到大排序,然后分情况贪心: 1.使其最终得分为sc+2: 只需要打赢前sc+2个人即可,没有其他人会影响到他. 2.最终得分为sc+1: 我们担心得分为sc的人因为没有被打赢,得分+1而排在zyg前面,所以应该先处理得分为sc的人,把他们都打赢. (同时也要打赢sc+1的人,

Host1Plus主机商8个机房测试IP体验

Host1Plus商家也算是比较老的海外主机商(英国),当初进入中国市场也是比较早的,记得那时候支持支付宝的海外主机商尤其的深受用户喜欢.因为我 们大部分网友.站长最多有一个支付宝,很少有双币信用卡或者贝宝支付美元的能力.不过后来几年,HOST1PLUS商家逐渐的落寞,主要原因在于其他商家 的出现,以及他们本身营销能力和产品的策略. 尤其是提供的虚拟主机和VPS主机,价格和方案不是太符合中国用户的口味,配置比较低,而且机房较 少.不过商家应该意识到这一点,在最近2年改动挺大的,今天公司业务正好有

[CSP-S模拟测试]:C(三分+贪心)

题目传送门(内部题46) 输入格式 第一行$3$个整数$n,m,t$.第二行$n$个整数,表示$P_i$.接下来$m$行每行两个整数,表示$L_i,R_i$. 输出格式 一行一个整数表示答案. 样例 样例输入: 3 3 26 2 51 12 23 3 样例输出: 11 数据范围与提示 样例解释: 最优方案为使用$2$次特殊加热器,$4$次$1$号加热器,$3$次$3$号加热器. 数据范围: 对于前$20\%$的数据:$t\geqslant n$对于另$30\%$的数据:$P_i\leqslant

[CSP-S模拟测试]:Emotional Flutter(贪心)

题目传送门(内部题51) 输入格式 第一行一个整数$t$表示数据组数.每组数据的第一行有三个整数$s,k,n$.第二行有$n$个整数$A_1,A_2,...,A_n$,依次表示黑白条的长度. 输出格式 若能通过输出$"TAK"$,否则输出$"NIE"$. 样例 样例输入: 22 8 72 5 6 3 2 1 22 8 41 6 7 4 样例输出: TAKNIE 数据范围与提示 样例解释: 数据范围: $30\%$的数据,$n\leqslant 1300$: $50\

[20191004机房测试] ZGY的早餐

ZGY 每天早上要从宿舍走路到机房,顺便从学校小卖部购买早饭,当然机智的 ZGY 一定会走最短路 学校的路可以看成一无向联通张图,图上有 n 个点,m 条边,每一个点都有一个唯一的编号 1~n 每一条边有一个边权,表示两个点之间的距离,ZGY 的宿舍在 S 点,机房在 T点,而小卖部在 H 点 现在 ZGY 想知道从宿舍经过小卖部到达机房的最短距离 不过因为在这个世界上有 Q个 ZGY,所以你必须回答 Q 个问题 很棒的数据分治题 读入里面说了会读入测试点编号-- 其实是很明显的暗示了-- 一半

[20191004机房测试] C++锦标赛

有一个比赛已经有 n 个人参加,并且互相之间已经进行了比赛 每一个人都有一个得分用于最后排名 你作为第 n + 1 个参赛者,需要与之前的每一个人打一场比赛,初始得分为 0 对于每场比赛,有两个人参加,不会存在平局,胜者得分增加 1,败者得分不变 最后按照得分从高到低来排名,假设有人与你最终得分相同 那么如果那个人曾经输给了你就会排在你后面,否则会排在你的前面 如果你赢了某个人,就需要消耗相应的 RP 值 现在你可以决定赢那些人,求最少需要消耗多少 RP 值才能到前k名 50分做法:还是枚举二进

[CSP-S模拟测试]:Graph(图论+贪心)

题目描述 给定一张$n$个点$m$条边的无向图,每条边连接两个顶点,保证无重边自环,不保证连通你想在这张图上进行若干次旅游,每次旅游可以任选一个点$x$作为起点,再走到一个与 $x$直接有边相连的点$y$,再走到一个与$y$直接有边相连的点$z$并结束本次旅游 作为一个旅游爱好者,你不希望经过任意一条边超过一次,注意一条边不能即正向走一次又反向走一次,注意点可以经过多次,在满足此条件下,你希望进行尽可能多次的旅游,请计算出最多能进行的旅游次数并输出任意一种方案 输入格式 第$1$行两个正整数$n