您的位置:首页 > 大数据 > 人工智能

Codeforces Good Bye 2017 F - New Year and Rainbow Roads

2017-12-30 13:26 411 查看
一、如果升序中没有G颜色点:

那么我们找到第一个B颜色点prb(prev-blue)和最后一个B颜色点sub(succ-blue),和第一个R颜色点prr(prev-red)和最后一个R颜色点suc(succ-red),最优的方案是:

cost=xsub−xprb+xsur−xprr

如果某个颜色也不存在,则记Δx=0。

二、考虑升序中G颜色点对图的划分:

无非几种情况:

[...]①G[...]②GG[]③G[...]④

①第一个G前还有其他点,比如说这样。

R1B1B2R2B3.........RiBkG

那么我们这么连接即可:

R1−R2−...−B1−B2−...−Ri|G|Bk

②两个G颜色点之间有其他元素

G1R1B1B2R2.........RiBkG2

那么我们有两种连接的方法:

Ⅰ.

R1|G1|B1−...−−...−Ri|G2|Bk

R与R相连,B与B相连

Ⅱ.

R1|G1|B1...−Rr−−Rr+1−...−−−−−−−−−−...−Bb−−Bb+1−...Ri|G2|Bk

将中间某两个点之间的边去掉,并把G1和G2连起来。

我们把最大的边剪掉。

对于Ⅰ和Ⅱ两种情况,取较小的cost即可。

③两个G颜色点之间没有其他元素

将G1和G2连接即可。

④最后一个G后还有其他点,仿照①即可。

上面基本上就是全部的思路,基于贪心。

#include <cstdio>
#include <queue>
using namespace std;
queue<int> is,b;char geto[5];
int m[300005];bool mb[300005],nb=true,nr=true,fb,fr;
int main(){
int i=0,n,pre,suc,sub,sur,prb,prr;double cost=0,mxb,mxr;
scanf("%d",&n);
for(int j=0;j<n;j++){
scanf("%d%s",&m[j],geto);
if(geto[0]=='G')is.push(j);
if(geto[0]=='B')mb[j]=true;
}
if(is.empty()){
prb=prr=0;sub=sur=n-1;
while(prb<n){if(mb[prb])break;prb++;}
while(prr<n){if(!mb[prr])break;prr++;}
if(prb!=n-1)while(sub>=0){if(mb[sub])break;sub--;}
if(prr!=n-1)while(sur>=0){if(!mb[sur])break;sur--;}
cost+=m[sub]-m[prb]+m[sur]-m[prr];
}else{
suc=is.front();is.pop();
while(i<suc){
if(mb[i]&&nb)cost+=m[suc]-m[i],nb=false;
if(!mb[i]&&nr)cost+=m[suc]-m[i],nr=false;
i++;
}
for(i++;i<n;i++){
nb=nr=false;fb=fr=true;mxb=mxr=-1;
pre=suc;if(!is.empty()){suc=is.front();is.pop();}

if(pre==suc){
i=n-1;
while(i>pre){
if(mb[i]&&!nb)cost+=m[i]-m[pre],nb=true;
if(!mb[i]&&!nr)cost+=m[i]-m[pre],nr=true;
i--;
}
break;
}else{
sub=prb=sur=prr=pre;
while(i<suc){
if(mb[i]){
sub=i;nb=true;
if(m[sub]-m[prb]>mxb)mxb=m[sub]-m[prb];
prb=sub;
}else{
sur=i;nr=true;
if(m[sur]-m[prr]>mxr)mxr=m[sur]-m[prr];
prr=sur;
}
i++;
}
if(nb||nr){
if(sub!=pre)mxb=max(mxb,(double)m[suc]-m[sub]);
if(sur!=pre)mxr=max(mxr,(double)m[suc]-m[sur]);
if(mxr==-1)cost+=((m[suc]-m[pre])<<1)-mxb;
else if(mxb==-1)cost+=((m[suc]-m[pre])<<1)-mxr;
else cost+=((m[suc]-m[pre])<<1)+min(0.0,m[suc]-m[pre]-mxb-mxr);
}else cost+=m[suc]-m[pre];
}
}
}
printf("%.0lf",cost);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: