思路来源: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)。
当然,这题目可以不用priority_queue
WA code:
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;int num[222];
int sum[222];bool cmp1(int a, int b){
return a > b;
}void work(int n, int m){
for(int i = 1; i <= n; i++){
scanf("%d", &num[i]);
sum[i] = sum[i-1] + num[i];//以 sum 数组记录 1 到 pos 的累计和
}int ans = -1e8;
for(int i = 1; i <= n; i++){
for(int j = i; j <= n; j++){
int tmp = sum[j] - sum[i-1];
int max_array[222], min_array[222];
int max_sum = 0, min_sum = 0;
int MAX = -1e8, MIN = 1e8;for(int k = i; k <= j; k++)
min_array[min_sum++] = num[k];
sort(min_array, min_array + min_sum + 1);
for(int k = 1; k < i; k++)
max_array[max_sum++] = num[k];
for(int k = j + 1; k <= n; k++)
max_array[max_sum++] = num[k];
sort(max_array, max_array + max_sum + 1, cmp1);
//m 次操作机会, 满足 Max 队列 和 Min 队列 非空, 并且Max 队列存在大于Min 队列最小元素 的元素
for(int i = 0; i < m && max_sum && min_sum && max_array[0] > min_array[0]; i++){
tmp += max_array[max_sum] - min_array[min_sum];
swap(max_array[max_sum], min_array[min_sum]);
sort(min_array, min_array + min_sum + 1);
sort(max_array, max_array + max_sum + 1, cmp1);
}
ans = max(ans, tmp);
}
}
printf("%d\n", ans);
}int main(){
int n, k;
while(EOF != scanf("%d%d", &n, &k))
work(n, k);
}
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\n", ans);
41 }
42
43 int main(){
44 int n, k;
45 while(EOF != scanf("%d%d", &n, &k))
46 work(n, k);
47 }
Codeforces Round #243 (Div. 2) C. Sereja and Swaps,码迷,mamicode.com