CodeForces - 426C Sereja and Swaps

题目链接

https://codeforces.com/problemset/problem/426/C

解题思路

先用前缀和求出每段区间的价值和;
暴力枚举区间,枚举到的区间要与剩余部分的元素进行交换;
交换规则:枚举到的区间从小到大排序,未枚举到的部分从大到小排序,用枚举到的区间中小的换未枚举到部分中大的,最多交换k次,若接下来的交换已经无法使枚举到的区间的价值和增加,也要break。

具体实现看代码

AC代码

//未用优先队列 139ms
#include<bits/stdc++.h>
#define ll long long

using namespace std;
const int N=210;
const int INF=0x3f3f3f3f;

bool cmp(int a,int b)
{
    return a>b;
}

int n,k,sum[N],a[N],b[N],c[N],ans=-INF;

int main()
{
    cin>>n>>k;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
        sum[i]=sum[i-1]+a[i];
    } 

    for(int i=1;i<=n;i++)
    for(int j=i;j<=n;j++)
    {
        int t=sum[j]-sum[i-1],nb=0,nc=0;
        for(int kk=i;kk<=j;kk++)    b[++nb]=a[kk];//b存枚举区间的各个元素价值
        for(int kk=1;kk<i;kk++)      c[++nc]=a[kk];//c存未枚举部分各个元素价值
        for(int kk=j+1;kk<=n;kk++)    c[++nc]=a[kk];
        sort(b+1,b+nb+1);//b从小到大排序
        sort(c+1,c+nc+1,cmp);//c从大到小排序
        for(int p=1;p<=nb && p<=nc && p<=k && c[p]>b[p];p++)//交换超过k次、交换超过总元素个数、接下来要交换的c中的比b小,都要退出循环
        t+=c[p]-b[p];//增量
        ans=max(ans,t);
    }
    cout<<ans<<endl;
}


//优先队列 140ms
#include<bits/stdc++.h>
#define ll long long

using namespace std;
const int N=210;
const int INF=0x3f3f3f3f;

int n,k,sum[N],a[N],ans=-INF;

priority_queue<int,vector<int>,greater<int> > b;
priority_queue<int> c;

int main()
{
    cin>>n>>k;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
        sum[i]=sum[i-1]+a[i];
    }
    for(int i=1;i<=n;i++)
    for(int j=i;j<=n;j++)
    {
        int sm=sum[j]-sum[i-1];
        for(int t=i;t<=j;t++)     b.push(a[t]);
        for(int t=1;t<i;t++)    c.push(a[t]);
        for(int t=j+1;t<=n;t++)    c.push(a[t]);

        for(int p=1;p<=k;p++)
        {
            if(b.empty() || c.empty()) break;
            int bb=b.top(),cc=c.top();
            b.pop(),c.pop();
            if(bb<cc) sm+=cc-bb;
            else break;
        }

        ans=max(ans,sm);
        while(!b.empty()) b.pop();
        while(!c.empty()) c.pop();
    }
    cout<<ans<<endl;
}

总结

看到数据规模很小,但还是不会……
还用到了前缀和小技巧,直接想不到

思维 文章被收录于专栏

思维题都会了,ACM金牌就稳了! 我骗你的!

全部评论

相关推荐

12-17 19:24
门头沟学院 Java
黑皮白袜臭脚体育生:看你后备隐藏能源多不多,最坏的情况就是每个星期的三天课程都不在周末,那么每个星期公司那边请一天半假,半天假请上午,上午正常上课,早点溜去请病假或者中午去请病假,然后坐高铁回公司,记得提前请学校那边实训课下午的病假,就说肚子痛,然后下午就公司上班,第二个实训周同样,但病假理由是牙齿痛,像肚子痛和牙齿痛这种校医院不方便查,会同意你出去检查的,很多时候都不需要你的检查报告,这里的问题就是最坏情况时距离过远的话可能要坐飞机才能赶上,然后请假的话不一定请了就有回应,可能要等老师,然后距离不远不近的情况到公司了也是迟到,得想个说辞掩盖一下,顺便晚上多加点班补下时间,特殊情况特殊处理,正常不建议加班常态化,这样每个星期可以多凑出来半天,老师面子也有了公司那边也不至于无法交差,就是有点费存粮,如果哪个星期的三天课有一天或两天在周末的话那就更好应对了。实习还是建议去,学校的课懂的都懂
点赞 评论 收藏
分享
评论
1
收藏
分享
牛客网
牛客企业服务