题目:http://community.topcoder.com/stat?c=problem_statement&pm=13256&rd=16008
参考:http://apps.topcoder.com/wiki/display/tc/SRM+627
首先要知道冒泡排序的swap次数怎样计算:等于 当 i < j 时,A[i] > A[j] 的 有序对(i, j)的数量。f(x ,p) 表示 "位置x及x之后在最大可以交换p次的情况下对swap的最小贡献数“,则对x位置的处理有两种情况,一是x位置不是reversal的一部分,则 f(x, p) = f(x + 1, p),二是x位置是一个reversal左端端点位置,则可以遍历右端端点位置y(取x+1 到 N - 1 ),则f(x, p) = min(位置x到yreverse后对swap的贡献 + f(y + 1, p -1) )。
代码:
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <iostream>
#include <sstream>
#include <iomanip>
#include <bitset>
#include <string>
#include <vector>
#include <stack>
#include <deque>
#include <queue>
#include <set>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cctype>
#include <cmath>
#include <cstring>
#include <ctime>
#include <climits>
using namespace std;
#define CHECKTIME() printf("%.2lf\n", (double)clock() / CLOCKS_PER_SEC)
typedef pair<int, int> pii;
typedef long long llong;
typedef pair<llong, llong> pll;
#define mkp make_pair
#define FOREACH(it, X) for(__typeof((X).begin()) it = (X).begin(); it != (X).end(); ++it)
/*************** Program Begin **********************/
int dp[51][51];
int xpairs[51]; // x位置对swap的贡献数
int revpairs[51][51]; // 保存位置x到y reverse后这些位置对swap的贡献数
class BubbleSortWithReversals {
public:
int N, K;
int rec(int x, int p) // x及x之后位置在最大可以交换p次的情况下对swap的最小贡献数
{
if (N == x) {
return 0;
}
int & res = dp[x][p];
if (-1 != res) {
return res;
}
// position x is not a reversal
res = xpairs[x] + rec(x + 1, p);
// position x is the begin of a reversal
if (p > 0) {
for (int y = x + 1; y < N; y++) { // right end of reversal
res = min(res, revpairs[x][y] + rec(y + 1, p - 1));
}
}
return res;
}
int getMinSwaps(vector <int> A, int K) {
int res = 0;
this->N = A.size();
this->K = K;
memset(xpairs, 0, sizeof(xpairs));
memset(revpairs, 0, sizeof(revpairs));
memset(dp, -1, sizeof(dp));
for (int i = 0; i < N; i++) {
for (int j = 0; j < i; j++) {
if (A[j] > A[i]) {
++xpairs[i];
}
}
}
for (int x = 0; x < N; x++) {
for (int y = x + 1; y < N; y++) {
for (int i = x; i <= y; i++) {
for (int j = 0; j < x; j++) {
if (A[j] > A[i]) {
++revpairs[x][y];
}
}
for (int j = i + 1; j <= y ; j++) {
if (A[j] > A[i]) {
++revpairs[x][y];
}
}
}
}
}
res = rec(0, K);
return res;
}
};
/************** Program End ************************/