码迷,mamicode.com
首页 > 其他好文 > 详细

CF:Problem 425A - Sereja and Swaps 区间交换最大值

时间:2014-07-22 23:03:35      阅读:339      评论:0      收藏:0      [点我收藏+]

标签:blog   os   2014   for   re   c   

这题比赛的时候不会做,原来是区间暴力。

其实理解起来也觉得挺简单的,可能是看题的时候被交换这个思想束缚了自己的解题吧,所以一直想不出什么好的做法,看了别人的解题茅舍顿开……

解法:就是在这个数列中先选出一段我们要求的区间,如果在中间取的这段的话,那旁边两段就是剩余的段,也就是我们需要至少k次交换剩余段中最大的值与刚开始选出的段交换最小的值,然后求这选出的这段的和,如此下去更新最大值就得到结果了。选出的段为 [ i , j ],剩余的段就是:[ 0 , i - 1 ] 与 [ j+1 , n - 1 ]。

如此暴力更新下去复杂度为 O(n^2log2n),n<=200,k<=10,所以1秒是可以接受的了……神奇!

#include <bits/stdc++.h>
#define PI acos(-1.0)
#define mem(a,b) memset(a,b,sizeof(a))
#define sca(a) scanf("%d",&a)
#define sc(a,b) scanf("%d%d",&a,&b)
#define pri(a) printf("%d\n",a)
#define lson i<<1,l,mid
#define rson i<<1|1,mid+1,r
#define MM 1000005
#define MN 2005
#define INF 100004
#define eps 1e-7
using namespace std;
typedef long long ll;
int main()
{
    int n,k,i,j,p,a[205],Max=-1000;
    sc(n,k);
    for(i=0;i<n;i++) sca(a[i]);
    for(i=0;i<n;i++)
        for(j=i;j<n;j++)
        {
            vector<int>u,v;
            for(p=0;p<n;p++)
                if(p<i||p>j) v.push_back(a[p]);//v是剩余的两边区间
                else u.push_back(a[p]);//u是所求区间[i,j]
            sort(v.rbegin(),v.rend());//降序
            for(p=0;p<k&&p<v.size();p++) //交换v区间中大的值给u区间
                u.push_back(v[p]);
            sort(u.rbegin(),u.rend()); //降序排序后前j-i个就是所需的了,后u.size()-(j-i)个就是交换出的最小值了
            int sum=0;
            for(p=0;p<=j-i;p++) sum+=u[p]; //相当于把大值与小值交换了
            Max=max(Max,sum);
        }
    pri(Max);
    return 0;
}


CF:Problem 425A - Sereja and Swaps 区间交换最大值,码迷,mamicode.com

CF:Problem 425A - Sereja and Swaps 区间交换最大值

标签:blog   os   2014   for   re   c   

原文地址:http://blog.csdn.net/u011466175/article/details/24725303

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!