[ACM_暴力] 最多交换k个数的顺序,求a[i]的最大连续和

 1 /*
 2 http://codeforces.com/contest/426/problem/C
 3 最多交换k个数的顺序,求a[i]的最大连续和
 4 爆解
 5 思路:Lets backtrack interval that should contain maximal sum. 
 6 To improve it we can swap not more then K minimal elements
 7  in fixed interval to not more K maximal elements not 
 8  contained in our interval. As n is quite little we can 
 9  do it in any way. Author solution works O(n3?*?log(n)).
10 */
11 #include <iostream>
12 #include <vector>
13 #include <string.h>
14 #include <algorithm>
15 #include <queue>
16 #include <set>
17 
18 using namespace std;
19 int sum[210][210],a[210];//sum[i][j]保存从i到j的和
20 int main(){
21     int n,k,i,j,o,ans;
22     cin>>n>>k;
23     for(i=0;i<n;i++) cin>>a[i];//输入
24     memset(sum,0,sizeof(sum));//清0
25     ans=-5000000;//最值
26     for(i=0;i<n;i++){
27         sum[i][i]=a[i];
28         if(sum[i][i]>ans) ans=sum[i][i];
29         for(j=i+1;j<n;j++){
30             sum[i][j]=sum[i][j-1]+a[j];
31             if(sum[i][j]>ans) ans=sum[i][j];
32         }
33     }
34     priority_queue<int> temp;
35     multiset<int> add;
36     for(i=0;i<n;i++){
37         for(j=i;j<n;j++){
38             for(o=i;o<=j;o++){//查找从i到j为负的最小的k个
39                 if(a[o]<0) temp.push(a[o]);
40                 if(temp.size()>k) temp.pop();
41             }
42             if((j-i+1)==temp.size()){//全为负
43                 sum[i][j]=temp.top();
44                 while(!temp.empty()) temp.pop();//清空
45             }
46             else{
47                 while(!temp.empty()){//清空
48                     sum[i][j]-=temp.top();//将负的移出
49                     temp.pop();
50                 }
51             }
52 
53             add.clear();//清空add
54             //对于非[i,j]部分取k个最大正数
55             for(o=i-1;o>=0;o--){
56                 if(a[o]>0) add.insert(a[o]);
57                 if(add.size()>k) add.erase(add.begin());
58             }
59             for(o=j+1;o<n;o++){
60                 if(a[o]>0) add.insert(a[o]);
61                 if(add.size()>k) add.erase(add.begin());
62             }
63             while(!add.empty()){
64                 sum[i][j]+=*add.begin();
65                 add.erase(add.begin());
66             }
67             if(sum[i][j]>ans) ans=sum[i][j];//更新ans
68         }
69     }
70     cout<<ans<<"
";
71     return 0;
72 }
原文地址:https://www.cnblogs.com/zjutlitao/p/3695915.html