As usual, Sereja has array a, its elements are integers: a[1], a[2], ..., a[n]. Let's introduce notation:
A swap operation is the following sequence of actions:
- choose two indexes i, j (i ≠ j);
- perform assignments tmp = a[i], a[i] = a[j], a[j] = tmp.
What maximum value of function m(a) can Sereja get if he is allowed to perform at most k swap operations?
Input
The first line contains two integers n and k (1 ≤ n ≤ 200; 1 ≤ k ≤ 10). The next line contains n integers a[1], a[2], ..., a[n] ( - 1000 ≤ a[i] ≤ 1000).
Output
In a single line print the maximum value of m(a) that Sereja can get if he is allowed to perform at most k swap operations.
Sample test(s)
input
10 2 10 -1 2 2 2 2 2 2 -1 10
output
32
input
5 10 -1 -1 -1 -1 -1
output
-1
思路:dp[i][j][k]表示i到j这一段与其他进行K次操作所能达到的最大和,只需给i到j这一段建个最小堆,外面那部分建个最大堆,每次从最小堆里拿一个和最大堆的交换即可。
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <queue> using namespace std; #define inf 0x3f3f3f3f #define maxn 220 int a[maxn]; int sum[maxn]; int dp[maxn][maxn][12]; inline int min(int a,int b) { return a>b?b:a; } inline int max(int a,int b) { return a>b?a:b; } struct Min { int aa; Min(){} Min(int x) { aa = x; } bool operator < (const Min & a)const { return aa > a.aa; } }; struct Max { int aa; Max(){} Max(int x) { aa = x; } bool operator < (const Max & a)const { return aa < a.aa; } }; priority_queue <Min> qmin; priority_queue <Max> qmax; int main() { //freopen("in.txt","r",stdin); int n,K; while(scanf("%d%d",&n,&K)==2) { for(int i = 1;i <= n;i++) scanf("%d",&a[i]); sum[0] = 0; for(int i = 1;i <= n;i++) sum[i] = sum[i-1] + a[i]; for(int i = 1;i <= n;i++) { for(int j = i;j <= n;j++) { int fuck = sum[j] - sum[i-1]; //这个就是区间的和。 while(!qmin.empty()) qmin.pop(); while(!qmax.empty()) qmax.pop(); for(int k = i;k <= j;k++) { qmin.push(Min(a[k])); } for(int k = 1;k < i;k++) { qmax.push(Max(a[k])); } for(int k = j+1;k <= n;k++) { qmax.push(Max(a[k])); } for(int k = 1;k <= K;k++) { int aa = 0,bb = 0; if((!qmin.empty()) && (!qmax.empty())) { aa = qmin.top().aa; bb = qmax.top().aa; qmin.pop(); qmax.pop(); fuck += bb - aa; qmin.push(Min(bb)); qmax.push(Max(aa)); } dp[i][j][k] = fuck; } } } int ans = -inf; for(int i = 1;i <= n;i++) for(int j = i;j <= n;j++) for(int k = 1;k <= K;k++) { ans = max(ans,sum[j] - sum[i-1]); ans = max(ans,dp[i][j][k]); } printf("%d\n",ans); } return 0; }