FZU Problem 2197 最小花费 简单贪心>

来源:互联网 发布:通过照片搜淘宝app 编辑:程序博客网 时间:2024/06/08 18:26
Problem 2197 最小花费

Accept: 210    Submit: 502
Time Limit: 1000 mSec    Memory Limit : 32768 KB

Problem Description

给一个长度为n(n <= 10^5)的“01”串,你可以任意交换一个为0的位和一个为1的位,若这两位相邻,花费为X,否则花费为Y。求通过若干次交换后将串中的“1”全部变换到“0”前面的最小花费。

Input

第一行一个整数T(1 <= T <= 10),表示测试数据的组数。接下来3*T行,每组数据三行,第一行为整数X(1 <= X <= 10^3),第二行为整数Y(X <= Y <= 10^3),第三行是“01”串。

Output

最小花费。

Sample Input

2121100120011

Sample Output

03

Source

福州大学第十二届程序设计竞赛

思路:
我们每次取最后的1来替代最前面的0,然后选择策略时,取min{(i-j)*x,y},i,j分别代表1,0所在的位置,也就是说在一步步交换,和一次性交换中取
代价最小的就好了

#include <iostream>#include <cstring>#include <stack>#include <cstdio>#include <cmath>#include <queue>#include <algorithm>#include <vector>#include <set>#include <map>const double eps=1e-8;const double PI=acos(-1.0);using namespace std;char s[100005];int a[100005];int main(){    int t;    scanf("%d",&t);    while(t--)    {        memset(s,0,sizeof(s));        int x,y;        scanf("%d %d",&x,&y);        scanf("%s",s);        int len=strlen(s);        int ans=0;        int mark=-1;        for(int i=len-1; i>=0; i--)        {            if(s[i]=='1')            {                for(int j=mark+1; j<i; j++)                {                    if(s[j]=='0')                    {                        mark=j;//标记一下当前位置已经交换好了,下次就不用一直从0开始找了。                        ans = min(ans + (i - j) * x, ans + y);                        swap(s[i],s[j]);                        break;                    }                }            }        }        printf("%d\n",ans);    }    return 0;}



原创粉丝点击