codeforces(convert to ones)【思维】

Convert to ones

http://codeforces.com/problemset/problem/998/C
codeforces(convert to ones)【思维】_第1张图片
codeforces(convert to ones)【思维】_第2张图片
任何一段0 1序列都可以看做是一串 0 然后用 1 切割开。首先,因为我们是要把目标串变成全1串,所以开头的1(和结尾的1)我们可以不去管它,所以我们可以把所有的串看做是这种(开头的1和结尾的1无所谓就全都省略)然后我们可以怎么做呢?例如:000 1000 10000 100 100这个串,因为上面操作的花费与段的长度无关,所以我们可以把相邻的1合成一个1,相邻的0合成一个0。所以原串就可以转化成 0 10 10 10 10。
假设0分成的段的数量是num。
第一种方法,我们可以选择第二段 10 ,对其进行倒置操作,所以整个串就变成了 0 01 10 10 10。然后再次合并相邻的1 和相邻的 0 ,原串变成了 0 10 10 10。然后在进行一次相同的操作,就变成了 0 10 10.以此类推,最后将变成 0 10,再倒置一次,变成 00 1,然后再对00 进行一次操作二即可。这种方法的花费为 (num-1)x+y。
第二种方法,我们直接对每一段0实施操作二,使得其变为全1串,这样的花费是num
y。
所以显然,当x<=y时,我们选择第一种方案,当x>y时,我们选择第二中方案,统计0的段数,直接输出结果即可。
说完了,贴代码

var n,i:longint;x,y,ans,p:int64;s:ansistring;
begin
readln(n,x,y);
readln(s);
for i:=1 to n do
  if s[i]='0' then inc(p);
if p=0 then writeln(0)
else
  if x>=y then
    begin
    for i:=2 to n do
      if(s[i]='1')and(s[i-1]='0')then ans:=ans+y;
    if s[n]='0' then inc(ans,y);write(ans);
    end
  else
    begin
    if s[1]='0' then p:=1 else p:=0;
    for i:=2 to n do
      if s[i]='0' then
        begin
        p:=p+1;
        if(p>1)and(s[i-1]='1')then inc(ans,x);
        end;
    inc(ans,y);write(ans);
    end;
end.

你可能感兴趣的:(思维)