zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    封装格式---FLV---文件格式解析
    高并发服务器---基础----IO模式和IO多路复用
    nginx---如何实现轻量级和高并发
    nginx---基础介绍
    H.264---SPS和PPS
    机器学习---算法---朴素贝叶斯
    机器学习---算法---Adaboost
    流媒体传输协议---STUN---基础
    H.264---指数哥伦布编码
    【linux】vim编辑器快捷键使用方法
  • 原文地址:https://www.cnblogs.com/wushuaiyi/p/3697454.html
Copyright © 2011-2022 走看看