【题目链接】:click here~~
【题目大意】:
给一个长度为n(n <= 10^5)的“01”串,你可以任意交换一个为0的位和一个为1的位,若这两位相邻,花费为X,否则花费为Y。求通过若干次交换后将串中的“1”全部变换到“0”前面的最小花费。
【解题思路】:看到题以为是道考算法的,想了想,朴素算法O(n^2)绝逼超时啊~~其实模拟一下,因为达到最终状态的只有一种,因此移动的步数是一定的,所以每次交换最前面的0和最后面的1,然后分别记录位置,取min((b-a*)*x,y),最后累加就是答案。
代码:
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;
const int N=1e5+10;
int num[N];
char str[N];
int t,bx,by,q,pos,ans;
int main()
{
scanf("%d",&t);
while(t--)
{
pos=0,ans=0;
scanf("%d",&bx);
scanf("%d",&by);
scanf("%s",str);
int len=strlen(str);
for(int i=len-1; i>0; --i)
{
if(str[i]=='1') num[pos++]=i;
}
for(int i=0,pos=0;i<len; ++i)
{
if(str[i]=='0')
{
if(num[pos]>i)
{
ans+=min((num[pos++]-i)*bx,by);
}
}
}
printf("%d\n",ans);
}
return 0;
}