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 ] ,则剩下的区间为[ 1 ,  i - 1 ]和[ j + 1 , n ],

将选定区间的最小值与剩下区间的最大值交换,使选定区间的和越来越大。

非常好的暴力方法啊。复杂度(n^2)*(nlogn + k*logn)。

use priority_queue:

use flag to save:

MY AC code:

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <queue>
 4 #include <algorithm>
 5 using namespace std;
 6 
 7 int num[222];
 8 int sum[222];
 9 
10 int cmp(const int &a, const int &b){
11     return a > b;
12 }
13 
14 void work(int n, int m){
15     for(int i = 1; i <= n; i++){
16         scanf("%d", &num[i]);
17         sum[i] = sum[i-1] + num[i];//以 sum 数组记录 1 到 pos 的累计和
18     }
19 
20     int ans = -1e8;
21     for(int i = 1; i <= n; i++){
22         for(int j = i; j <= n; j++){
23             int tmp = sum[j] - sum[i-1];
24             int max_array[222], min_array[222];
25             int max_flag, min_flag;
26             int max_sum = 0, min_sum = 0;
27             int MAX = -1e8, MIN = 1e8;
28 
29             for(int k = i; k <= j; k++){
30                 min_array[min_sum++] = num[k];
31                 if(num[k] < MIN){
32                     MIN = num[k];
33                     min_flag = min_sum - 1;
34                 }
35             }
36             for(int k = 1; k < i; k++){
37                 max_array[max_sum++] = num[k];
38                 if(num[k] > MAX){
39                     MAX = num[k];
40                     max_flag = max_sum - 1;
41                 }
42             }
43             for(int k = j + 1; k <= n; k++){
44                 max_array[max_sum++] = num[k];
45                 if(num[k] > MAX){
46                     MAX = num[k];
47                     max_flag = max_sum - 1;
48                 }
49             }
50             //m 次操作机会, 满足 Max 队列 和 Min 队列 非空, 并且Max 队列存在大于Min 队列最小元素 的元素
51             for(int k = 0; k < m && max_sum && min_sum && max_array[max_flag] > min_array[min_flag]; k++){
52                 tmp += max_array[max_flag] - min_array[min_flag];
53                 swap(max_array[max_flag], min_array[min_flag]);
54                 int MAX = -1e8, MIN = 1e8;
55                 for(int z = 0; z < min_sum; z++){
56                     if(min_array[z] < MIN){
57                         MIN = min_array[z];
58                         min_flag = z;
59                     }
60                 }
61                 for(int z = 0; z < max_sum; z++){
62                     if(max_array[z] > MAX){
63                         MAX = max_array[z];
64                         max_flag = z;
65                     }
66                 }
67             }
68             ans = max(ans, tmp);
69         }
70     }
71     printf("%d
", ans);
72 }
73 
74 int main(){
75     int n, k;
76     while(EOF != scanf("%d%d", &n, &k)){
77         work(n, k);
78     }
79 }
priority_queue:
 1 #include <cstdio>
 2 #include <cstring>
 3 #include <queue>
 4 #include <algorithm>
 5 using namespace std;
 6 
 7 int num[222];
 8 int sum[222];
 9 
10 void work(int n, int m){
11     for(int i = 1; i <= n; i++){
12         scanf("%d", num+i);
13         sum[i] = sum[i-1] + num[i];//以 sum 数组记录 1 到 pos 的累计和
14     }
15 
16     int ans = -1e8;
17     for(int i = 1; i <= n; i++){
18         for(int j = i; j <= n; j++){
19             int tmp = sum[j] - sum[i-1];
20 
21             priority_queue<int> Max, Min;
22             for(int k = i; k <= j; k++)
23                 Min.push(-num[k]);
24             for(int k = 1; k < i; k++)
25                 Max.push(num[k]);
26             for(int k = j + 1; k <= n; k++)
27                 Max.push(num[k]);
28 
29             //m 次操作机会, 满足 Max 队列 和 Min 队列 非空, 并且Max 队列存在大于Min 队列最小元素 的元素
30             for(int i = 0; i < m && !Max.empty() && !Min.empty() && Max.top() + Min.top()>0; i++){
31                 tmp += Max.top() + Min.top();
32                 Max.push(-Min.top());
33                 Min.push(-Max.top());
34                 Max.pop();
35                 Min.pop();
36             }
37             ans = max(ans, tmp);
38         }
39     }
40     printf("%d
", ans);
41 }
42 
43 int main(){
44     int n, k;
45     while(EOF != scanf("%d%d", &n, &k))
46         work(n, k);
47 }
原文地址:https://www.cnblogs.com/wushuaiyi/p/3697454.html