ICPC昆明(A AC)

						A AC
题意: 
    给你一个长度为n的字符串,你最多修改k次,问你字符串中最多能有多少个ac。
    并要求你输出修改后的字符串。
思路:
    让c[i]代表将str[i]变成'a',str[i+1]变成'c'所需要的最小花费。
    然后问题变成了在花费不超过k的情况下,最多可以选择多少个互不相邻的位置i。
    此时如果不考虑输出修改后的字符串,问题就变成了一个典型的反悔贪心问题。
    用堆维护实现。
    然后字符串的输出发现也可以利用上面代码上的 l数组,r数组维护。
    就是每个区间(l[i],r[i])都变成了很多个 'ac' 。
    此时这个问题就解决了。
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+15;
typedef long long ll;
ll n,m,a[N],vis[N],l[N],r[N],pl[N],pr[N],mp[N];
char str[N];
struct node{
    int id,val;
    bool operator < (const node &b) const{
    return val>b.val;
    }
};
priority_queue<node>q;
void solve()
{
    ll cnt=0,w=0;
    node tp,nd;
    pl[0]=pr[0]=0;
    pl[n]=pr[n]=n;
    for(int i=1;i<=n-1;i++)
    {
        tp.id=i;
        l[i]=i-1;   r[i]=i+1;
        pl[i]=i;  pr[i]=i;
        tp.val=a[i]=(str[i]!='a')+(str[i+1]!='c');
        q.push(tp);
    }
    //l[0]=-1;
    r[0]=1; l[n+1]=n;
    l[n]=n-1;   r[n]=n+1;
    a[0]=a[n]=112345678;
    while(!q.empty())
    {
        tp=q.top();
        int id=tp.id,v=tp.val;
        if(vis[id]){
            q.pop();    continue;
        }
        if(w+v>m)
            break;
        q.pop();
        cnt++;  w+=v;
        mp[id]=1;   vis[l[id]]=vis[r[id]]=1;
        nd.val=a[l[id]]+a[r[id]]-a[id];
        //pl[id]--;   pr[id]++;
        pl[id]=pl[l[id]];   pr[id]=pr[r[id]];
      //  cout<<id<<" "<<pl[id]<<" "<<pr[id]<<endl;
        l[id]=l[l[id]]; r[l[id]]=id;
        r[id]=r[r[id]]; l[r[id]]=id;
        nd.id=id;
        a[id]=nd.val;
        q.push(nd);
    }
    cout<<cnt<<endl;
    for(int i=1;i<=n;i++)
    {
        if(mp[i]&&!vis[i])
        for(int j=pl[i]+1;j+1<=pr[i]&&j+1<=n;j+=2)
        {
            str[j]='a'; str[j+1]='c';
        }
    }
    cout<<(str+1)<<endl;
}
int main()
{
    cin>>n>>m;
    scanf("%s",str+1);
    solve();
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值