题目链接:https://codeforces.com/contest/1287/problem/C
题意:
有一个由1-n构成的数列,其中部分被删除(删除的元素由0代替),请用被删除的元素补全这个数列,使这个数列中相邻元素奇偶性不同的对数最少。
想法:
我们容易知道每添加的一个数都对它后面的一个数有直接的影响
贴上代码:
#include <algorithm> #include <string> #include <string.h> #include <vector> #include <map> #include <stack> #include <set> #include <queue> #include <math.h> #include <cstdio> #include <iomanip> #include <time.h> #include <bitset> #include <cmath> #include <sstream> #include <iostream> #include <cstring> #define LL long long #define ls nod<<1 #define rs (nod<<1)+1 #define pii pair<int,int> #define mp make_pair #define pb push_back #define INF 0x3f3f3f3f const double eps = 1e-10; const int maxn = 100 + 10; const LL mod = 1e9 + 7; int sgn(double a){return a < -eps ? -1 : a < eps ? 0 : 1;} using namespace std; int a[110]; int f[maxn][maxn][maxn][2]; int vis[2]; int ans,n; int main() { scanf("%d",&n); ans = INF; if (n % 2 == 0) { vis[0] = vis[1] = n / 2; } else { vis[0] = n / 2; vis[1] = (n+1) / 2; } for (int i = 1;i <= n;i++) { scanf("%d",&a[i]); if (a[i] != 0) { vis[a[i] % 2]--; a[i] %= 2; } else { a[i] = -1; } } memset(f,0x3f, sizeof(f)); if (a[1] == -1) { if (vis[0] >= 1) f[1][vis[0] - 1][vis[1]][0] = 0; if (vis[1] >= 1) f[1][vis[0]][vis[1] - 1][1] = 0; } else f[1][vis[0]][vis[1]][a[1]] = 0; for (int i = 2;i <= n;i++) { if (a[i] != -1) { for (int l1 = vis[0];l1 >= 0;l1--) { for (int l2 = vis[1];l2 >= 0;l2--) { f[i][l1][l2][a[i]] = min(f[i][l1][l2][a[i]],f[i-1][l1][l2][1]+(a[i] == 0)); f[i][l1][l2][a[i]] = min(f[i][l1][l2][a[i]],f[i-1][l1][l2][0]+(a[i] == 1)); } } continue; } for (int l1 = vis[0];l1 >= 0;l1--) { for (int l2 = vis[1]; l2 >= 0; l2--) { f[i][l1][l2][1] = min(f[i][l1][l2][1],f[i-1][l1][l2+1][0]+1); f[i][l1][l2][1] = min(f[i][l1][l2][1],f[i-1][l1][l2+1][1]); f[i][l1][l2][0] = min(f[i][l1][l2][0],f[i-1][l1+1][l2][0]); f[i][l1][l2][0] = min(f[i][l1][l2][0],f[i-1][l1+1][l2][1]+1); } } } printf("%d ",min(f[n][0][0][0],f[n][0][0][1])); return 0; }