【题目链接】: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; }
原文地址:http://blog.csdn.net/u013050857/article/details/46582799