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

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

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

解法:就是在这个数列中先选出一段我们要求的区间,如果在中间取的这段的话,那旁边两段就是剩余的段,也就是我们需要至少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

时间: 2024-12-10 03:59:24

CF:Problem 425A - Sereja and Swaps 区间交换最大值的相关文章

Codeforces 425A Sereja and Swaps(暴力枚举)

题目链接:A. Sereja and Swaps 题意:给定一个序列,能够交换k次,问交换完后的子序列最大值的最大值是多少 思路:暴力枚举每一个区间,然后每一个区间[l,r]之内的值先存在优先队列内,然后找区间外假设有更大的值就替换掉. 求出每一个区间的最大值,最后记录下全部区间的最大值 代码: By lab104_yifan, contest: Codeforces Round #243 (Div. 2), problem: (C) Sereja and Swaps, Accepted, #

CodeForces 425A Sereja and Swaps

题意: 一串数字  最多可以做k次交换数字  求  最大连续和是多少 思路: n^2暴力枚举所有区间  那么如果要换数字  一定是从区间外拿大数换区间内的小数  优先队列可以完成操作 代码: #include<cstdio> #include<cstring> #include<algorithm> #include<queue> using namespace std; #define N 201 int n,m,ans; int a[N]; priori

CF:Problem 426B - Sereja and Mirroring 二分或者分治

这题解法怎么说呢,因为我是把行数逐步除以2暴力得到的答案,所以有点二分的意思,但是昨天琦神说是有点像分治的意思,反正总的来说:就是从大逐步细化找到最优答案. 但是昨晚傻B了,靠!多写了点东西,然后就错了,刚才一练习,拿昨晚的代码一看,就把6行代码删去就过了,靠!昨晚应该是脑子进水了!!!!! 昨晚的代码: #include <iostream> #include <cstdio> #include <fstream> #include <algorithm>

Codeforces Round #243 (Div. 2) C. Sereja and Swaps

思路来源:http://blog.csdn.net/sf____/article/details/24626739 题目给出数据上限为200, 所以可以暴利所有区间. 解题思路: for i in range(n): for j in range(n): create priority_queue for w in range(k): if(Max.top > Min.top) SWAP(Max[element], Min[element]) 暴利枚举所有初始区间 [ i , j ] ,则剩下的

CF243 DIV2 C Sereja and Swaps(暴力)

题意:给你一个数组,问你交换最多K个数以后,最大子串和为多少; 解题思路:枚举这个数组最大字串和的起点和终点,然后优先队列交换这段里面的小数去换外面的大数,即可求出答案! 解题代码: 1 // File Name: c.cpp 2 // Author: darkdream 3 // Created Time: 2014年04月28日 星期一 19时04分36秒 4 5 #include<vector> 6 #include<list> 7 #include<map> 8

Codeforces Round #243 (Div. 2) C. Sereja and Swaps(优先队列 暴力)

题目 题意:求任意连续序列的最大值,这个连续序列可以和其他的 值交换k次,求最大值 思路:暴力枚举所有的连续序列.没做对是因为 首先没有认真读题,没看清交换,然后,以为是dp或者贪心 用了一下贪心,各种bug不对. 这次用了一下优先队列,以前用的不多,看这个博客又学了一下 AC代码: 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cstdlib> 5 #i

POJ 3468 A Simple Problem with Integers(线段树区间更新)

题目地址:POJ 3468 打了个篮球回来果然神经有点冲动..无脑的狂交了8次WA..居然是更新的时候把r-l写成了l-r... 这题就是区间更新裸题.区间更新就是加一个lazy标记,延迟标记,只有向下查询的时候才将lazy标记向下更新.其他的均按线段树的来就行. 代码如下: #include <iostream> #include <cstdio> #include <cstring> #include <math.h> #include <stac

CF:Problem 427C - Checkposts强连通Tarjan算法

这题昨晚做了,刚开始看题的时候没想出好法子,然后就看D题了,一看D题发现是后缀数组,然后就把模板改了点就交了上去--不幸的是--WA了,然后重新看题,果然题目看漏了--不仅要用后缀数组和前缀数组求出公共子缀,还要是求最小的,而且在每个串里都不能重复的,这下就想了会不会了,然后看见大帝C过了,然后就重新回来看C了,看了会终于明天怎么做了. C题意:给个图,然后每个点都有权值,求最小的花费及方案数:最小的花费是这样的:因为是建立一个岗哨,然后这个岗哨可以管哪些呢,可以管 i = j 的,或者可以从

CF:Problem 427C - Checkposts强连通 Tarjan算法

tarjan算法第一题 喷我一脸....把手写栈的类型开成了BOOL,一直在找错... #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define maxn 100005 const int MOD=1000000007; using namespace std; struct node { int to,next; }edge[maxn*3]; int