cf#243-div1-A. Sereja and Swaps-暴力枚举+multiset+优先队列

102 篇文章 0 订阅
31 篇文章 0 订阅

http://codeforces.com/problemset/problem/425/A

题意:给你n个数,给你k(n<=200,k<=10)

让你至多交换k对数,使得该序列的最大连续区间和最大


思路:

n比较小,直接枚举这个最大连续区间和的两端i,j。 (n^2)

对于每次枚举,我直接把i到j的元素丢到multiset,然后把两边剩余的求到优先队列里,做k次,每次从multiset取最小的,从优先队列取最大的,如果优先队列里取的最大值比set里的最小值大,就可以交换,以得到更大值,否则break

(注意容器为空的时候就不要取了,否则RE)

每次枚举更新答案即可


复杂度n^2(nlogn+klogn)。。。勉勉强强过得去吧

#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <iostream>
#include <queue>
#include <map>
#include <set>
#include <vector>
using namespace std;

int tm[205]; 

multiset<int> ans; 
priority_queue<int> sb;  
multiset<int>::iterator it;
int main()
{
	 

	int n,m;  
	cin>>n>>m;
	int i,j,k;
	   for (i=1;i<=n;i++)
		   scanf("%d",&tm[i]);
	   
	   
	   int ans_max=-1000*205;
	   for (i=1;i<=n;i++)
	   {
		   for (j=i;j<=n;j++)
		   {
			   while(!sb.empty()) sb.pop();
			   ans.clear();
			   for (k=i;k<=j;k++) 
				   ans.insert(tm[k]); 
			   
			   for (k=1;k<i;k++) 
				   sb.push(tm[k]); 
			   for (k=j+1;k<=n;k++) 
				   sb.push(tm[k]); 
			   
			   int tmp=m;
			   while(tmp--)
			   {
				   if (!sb.empty())
				   {
				   int minn=*ans.begin();
				   int maxx=sb.top(); 
				   if (maxx>minn)
				   {
					   sb.pop();
					   ans.erase(ans.find(minn));
					   ans.insert(maxx);
					   sb.push(minn);
				   }
				   else
					   break;
				   }
			   }
			   int cun=0;
			   for(it=ans.begin();it!=ans.end();it++) 
				   cun+=*it;
			   
			   if (cun>ans_max) 
				   ans_max=cun;
			   
		   }
	   }
	   printf("%d\n",ans_max);
	   
	   return 0;
	   
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值