Codeforces Round #612 (Div. 2) C. Garland 动态规划

Codeforces Round #612 (Div. 2) C. Garland 动态规划

题目链接: https://codeforces.com/contest/1287/problem/C

C. Garland

time limit per test

1 second

memory limit per test

256 megabytes

input

standard input

output

standard output

Vadim loves decorating the Christmas tree, so he got a beautiful garland as a present. It consists of nn light bulbs in a single row. Each bulb has a number from 11 to nn (in arbitrary order), such that all the numbers are distinct. While Vadim was solving problems, his home Carp removed some light bulbs from the garland. Now Vadim wants to put them back on.

Codeforces Round #612 (Div. 2) C. Garland 动态规划

Vadim wants to put all bulb back on the garland. Vadim defines complexity of a garland to be the number of pairs of adjacent bulbs with numbers with different parity (remainder of the division by 22). For example, the complexity of 1 4 2 3 5 is 22 and the complexity of 1 3 5 7 6 4 2 is 11.

No one likes complexity, so Vadim wants to minimize the number of such pairs. Find the way to put all bulbs back on the garland, such that the complexity is as small as possible.

Input

The first line contains a single integer nn (1≤n≤1001≤n≤100) — the number of light bulbs on the garland.

The second line contains nn integers p1, p2, …, pnp1, p2, …, pn (0≤pi≤n0≤pi≤n) — the number on the ii-th bulb, or 00 if it was removed.

Output

Output a single number — the minimum complexity of the garland.

Examples

input

Copy

5
0 5 0 2 3

output

Copy

2

input

Copy

7
1 0 0 5 0 0 2

output

Copy

1

Note

In the first example, one should place light bulbs as 1 5 4 2 3. In that case, the complexity would be equal to 2, because only (5,4)(5,4) and (2,3)(2,3) are the pairs of adjacent bulbs that have different parity.

In the second case, one of the correct answers is 1 7 3 5 6 4 2.

题意:

给定一个整数n,

以及一个n的全排列,现在将全排列中的一些数字抹掉为0.

问你将抹掉的数字以任意位置填回去后,槽糕值最低是多少?

定义一个排列的糟糕值为这样的位置i的个数:

a[i] 和a[i+1] 的奇偶性不同。

 思路:

很容易想到用DP来解决该问题:

我们定义DP 状态为:

\(dp[i][j][0]\) 到第i个位置,还剩j个偶数没用,第i个位置是偶数的最小糟糕值。

\(dp[i][j][1]\) 到第i个位置,还剩j个偶数没用,第i个位置是奇数的最小糟糕值。

初始化:

如果n大于1,并且第一个数a[1] 为0或者偶数,

令\(dp[1][n/2-1][0]=0\)

如果第一个数a[1] 为0或者奇数,

令\(dp[1][n/2][1]=0\)

转移方程见代码

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <vector>
#include <iomanip>
#define ALL(x) (x).begin(), (x).end()
#define sz(a) int(a.size())
#define rep(i,x,n) for(int i=x;i<n;i++)
#define repd(i,x,n) for(int i=x;i<=n;i++)
#define pii pair<int,int>
#define pll pair<long long ,long long>
#define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define MS0(X) memset((X), 0, sizeof((X)))
#define MSC0(X) memset((X), '\0', sizeof((X)))
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define eps 1e-6
#define chu(x) cout<<"["<<#x<<" "<<(x)<<"]"<<endl
#define du3(a,b,c) scanf("%d %d %d",&(a),&(b),&(c))
#define du2(a,b) scanf("%d %d",&(a),&(b))
#define du1(a) scanf("%d",&(a));
using namespace std;
template<typename T> inline T max(T a, T b) {return a > b ? a : b;}
template<typename T> inline T min(T a, T b) {return a < b ? a : b;}
template<typename T> inline T abs(T a) {return a > 0 ? a : -a;}
typedef long long ll;
ll gcd(ll a, ll b) {return b ? gcd(b, a % b) : a;}
ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}
ll powmod(ll a, ll b, ll MOD) { if (a == 0ll) {return 0ll;} a %= MOD; ll ans = 1; while (b) {if (b & 1) {ans = ans * a % MOD;} a = a * a % MOD; b >>= 1;} return ans;}
void Pv(const vector<int> &V) {int Len = sz(V); for (int i = 0; i < Len; ++i) {printf("%d", V[i] ); if (i != Len - 1) {printf(" ");} else {printf("\n");}}}
void Pvl(const vector<ll> &V) {int Len = sz(V); for (int i = 0; i < Len; ++i) {printf("%lld", V[i] ); if (i != Len - 1) {printf(" ");} else {printf("\n");}}}
inline long long readll() {long long tmp = 0, fh = 1; char c = getchar(); while (c < '0' || c > '9') {if (c == '-') fh = -1; c = getchar();} while (c >= '0' && c <= '9') tmp = tmp * 10 + c - 48, c = getchar(); return tmp * fh;}
inline int readint() {int tmp = 0, fh = 1; char c = getchar(); while (c < '0' || c > '9') {if (c == '-') fh = -1; c = getchar();} while (c >= '0' && c <= '9') tmp = tmp * 10 + c - 48, c = getchar(); return tmp * fh;}
const int maxn = 110;
const int inf = 0x3f3f3f3f;
/*** TEMPLATE CODE * * STARTS HERE ***/
int n;
int a[maxn];
int dp[maxn][maxn][3];

int main()
{
    //freopen("D:\\code\\text\\input.txt","r",stdin);
    //freopen("D:\\code\\text\\output.txt","w",stdout);
    gbtb;
    cin >> n;
    repd(i, 1, n)
    {
        cin >> a[i];
    }
    repd(i, 1, n)
    {
        repd(j, 0, n)
        {
            dp[i][j][0] = dp[i][j][1] = inf;
        }
    }
    if (n > 1 && a[1] % 2 == 0)
    {
        dp[1][n / 2 - 1][0] = 0;
    }
    if (a[1] == 0 || a[1] & 1)
    {
        dp[1][n / 2][1] = 0;
    }
    repd(i, 2, n)
    {
        repd(j, 0, n / 2)
        {
            if (j > 0 && !(a[i] & 1))
            {
                dp[i][j - 1][0] = min(dp[i][j - 1][0], dp[i - 1][j][1] + 1);
                dp[i][j - 1][0] = min(dp[i][j - 1][0], dp[i - 1][j][0]);
            }
            if (i + j <= n && (a[i] == 0 || (a[i] & 1)))
            {
                dp[i][j][1] = min(dp[i][j][1], dp[i - 1][j][1]);
                dp[i][j][1] = min(dp[i][j][1], dp[i - 1][j][0] + 1);
            }
        }
    }
    cout << min(dp[n][0][0], dp[n][0][1]) << endl;
    return 0;
}
上一篇:反转整数


下一篇:7.整数反转