[ An Ac a Day ^_^ ] CodeForces 426C Sereja and Swaps 优先队列

题意:

给你一个有n个数的序列 取一个区间 这个区间内的数可以与区间外的值交换k次 问这样的区间最大值是多少

 

思路:

看数据是200 时间复杂度O(n*n) 应该可以暴力 顺便学习一下优先队列

 枚举区间 每次将区间内最小的数和区间外最大的值交换然后更新和

 

 1 #include<stdio.h>
 2 #include<iostream>
 3 #include<algorithm>
 4 #include<math.h>
 5 #include<string.h>
 6 #include<string>
 7 #include<map>
 8 #include<set>
 9 #include<vector>
10 #include<queue>
11 #define M(a,b) memset(a,b,sizeof(a))
12 using namespace std;
13 typedef long long ll;
14 const int inf=0x3f3f3f3f;
15 int num[205],n,k;
16 bool vis[205];
17 struct cmp{ //优先队列优先级 最小值优先
18     bool operator() (int &a,int &b){
19         return a>b;
20     }
21 };
22 int solve(int l,int r){ 
23     priority_queue<int,vector<int>,cmp>q;
24     int sum=0;
25     for(int i=l;i<=r;i++){
26         sum+=num[i]; 
27         q.push(num[i]); //区间内的数入队
28     }
29     int time=k;
30     M(vis,false);
31     while(time--){ //将区间内最小的数和区间外最大的值交换
32         int max_x=-0x3f3f3f,loc;
33         for(int i=0;i<n;i++){ //找出区间外最大的数
34             if(i>=l&&i<=r||vis[i]) continue;
35             if(max_x<num[i]){ 
36                 max_x=num[i];
37                 loc=i; //记录区间外最大的数的位置
38             }
39         }
40         int max_y=q.top();
41         if(max_y<max_x){
42             vis[loc]=true;
43             sum-=(max_y-max_x);
44             q.pop(); //区间内最小的数出队
45             q.push(max_x); //区间外最大的数入队
46         }
47     }
48     return sum;
49 }
50 int main(){
51     int ans=-0x3f3f3f; //因为数据范围是[-1000,1000] 所以不能用-1
52     scanf("%d%d",&n,&k);
53     for(int i=0;i<n;i++)
54         scanf("%d",&num[i]);
55     for(int i=0;i<n;i++) //枚举区间
56         for(int j=i;j<n;j++)
57             if(ans<solve(i,j)) 
58                 ans=solve(i,j); //更新最大值
59     printf("%d\n",ans);
60     return 0;
61 }
62 /*
63 
64 10 2
65 10 -1 2 2 2 2 2 2 -1 10
66 
67 5 10
68 -1 -1 -1 -1 -1
69 
70 */

 

posted @ 2016-09-05 21:17  良将ℓ  阅读(162)  评论(0编辑  收藏  举报