[ 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 */