您的位置:首页 > 其它

Codeforces Round #243 (Div. 2) C. Sereja and Swaps

2014-04-28 21:05 337 查看
思路来源: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:

#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;

int num[222];
int sum[222];

int cmp(const int &a, const 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_flag, min_flag;
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];
if(num[k] < MIN){
MIN = num[k];
min_flag = min_sum - 1;
}
}
for(int k = 1; k < i; k++){
max_array[max_sum++] = num[k];
if(num[k] > MAX){
MAX = num[k];
max_flag = max_sum - 1;
}
}
for(int k = j + 1; k <= n; k++){
max_array[max_sum++] = num[k];
if(num[k] > MAX){
MAX = num[k];
max_flag = max_sum - 1;
}
}
//m 次操作机会, 满足 Max 队列 和 Min 队列 非空, 并且Max 队列存在大于Min 队列最小元素 的元素
for(int k = 0; k < m && max_sum && min_sum && max_array[max_flag] > min_array[min_flag]; k++){
tmp += max_array[max_flag] - min_array[min_flag];
swap(max_array[max_flag], min_array[min_flag]);
int MAX = -1e8, MIN = 1e8;
for(int z = 0; z < min_sum; z++){
if(min_array[z] < MIN){
MIN = min_array[z];
min_flag = z;
}
}
for(int z = 0; z < max_sum; z++){
if(max_array[z] > MAX){
MAX = max_array[z];
max_flag = z;
}
}
}
ans = max(ans, tmp);
}
}
printf("%d\n", ans);
}

int main(){
int n, k;
while(EOF != scanf("%d%d", &n, &k)){
work(n, k);
}
}


priority_queue:


#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;

int num[222];
int sum[222];

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];

priority_queue<int> Max, Min;
for(int k = i; k <= j; k++)
Min.push(-num[k]);
for(int k = 1; k < i; k++)
Max.push(num[k]);
for(int k = j + 1; k <= n; k++)
Max.push(num[k]);

//m 次操作机会, 满足 Max 队列 和 Min 队列 非空, 并且Max 队列存在大于Min 队列最小元素 的元素
for(int i = 0; i < m && !Max.empty() && !Min.empty() && Max.top() + Min.top()>0; i++){
tmp += Max.top() + Min.top();
Max.push(-Min.top());
Min.push(-Max.top());
Max.pop();
Min.pop();
}
ans = max(ans, tmp);
}
}
printf("%d\n", ans);
}

int main(){
int n, k;
while(EOF != scanf("%d%d", &n, &k))
work(n, k);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: