题目:
题目概述:
有 1- n 的某种排列,从排列中拿走某些数后再把这些数放回空位中,求最小的complexity.
complexity定义为:相邻两个数的奇偶性不同complexity + 1.
动态规划:
我们关心的只是奇偶性,所以直接用 0 和 1来替代
dp[id][odd][even][pre]定义为当前遍历到第 id 位,且还剩下odd个奇数没有填,even个偶数没有填的最小复杂度,最后我们返回dp[0][odd][even][-1]
代码实现:
#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>
#include <numeric>
int dp[101][101][101][2];
vector<int> a;
int N;
int min(int a, int b) {
if (a > b) return b;
return a;
}
int dfs(int id, int oddnum, int evennum, int pre) {
if (id == N) {
return 0;
}
if (pre == -1) {
int x = 0; int y = 0;
if (a[id] == 0) {
if (oddnum > 0)
x = dfs(id + 1, oddnum - 1, evennum, 1);
if (evennum > 0)
y = dfs(id + 1, oddnum, evennum - 1, 0);
return min(x, y);
}
else {
return dfs(id + 1, oddnum, evennum, a[0] % 2);
}
}
if (dp[id][oddnum][evennum][pre] != -1) return dp[id][oddnum][evennum][pre];
dp[id][oddnum][evennum][pre] = 0;
int res = INT_MAX;
if (a[id] != 0) {
res = dfs(id + 1, oddnum, evennum, a[id] % 2) + (a[id] % 2 != pre);
dp[id][oddnum][evennum][pre] = res;
return res;
}
if (oddnum > 0) {
res = dfs(id + 1, oddnum - 1, evennum, 1) + (pre == 0);
}
if (evennum > 0) {
res = min(res, dfs(id + 1, oddnum, evennum - 1, 0) + (pre == 1));
}
dp[id][oddnum][evennum][pre] = res;
return res;
}
int main() {
N = 0;
cin >> N;
a.resize(N);
int odd = N / 2 + N % 2;
int even = N / 2;
for (int i = 0; i < N; i++) {
cin >> a[i];
if (a[i] == 0) continue;
else if (a[i] % 2 == 1) odd--;
else even--;
}
memset(dp, -1, sizeof(dp));
cout<< dfs(0, odd, even, -1);
}