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.
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.
==
=========================================================================
很有思维价值的一道题目,首先考虑0段的分类,无非三类
结尾开头行 即 000x , x000类型 ,
两段不同型 即 奇0000偶
两端相同型 即 偶0000偶
分别对这三种情况进行研究,第一种的情况,若全部与x奇偶性相同,则必定贡献0,否则一定是1,绝对不会是2
第二种情况,易知最差最坏都是1,无论几个偶数几个奇数
第三种情况,易知最好是0,最差就是2,且只有2这一种情况
那么就显而易见了,很重要的一点就是题目问的是数目,注意是数目,也就是不要往构造出这一整个序列方面去想。
由于第二种情况已经确定,故我们只需要暴力求解第一第三即可
设dp[i][j][k]为 前i段 ,使用了j个奇数,k个偶数时的最小答案, 枚举i,j,k与当前的奇数选择个数即可
还要加上之前就有的,外加第二种情况的个数,细节很多,但理解之后就很容易调试了
# include<bits/stdc++.h>
using namespace std;
# define mod 1000000007
typedef long long int ll;
vector<int>v1,v2;
int book[1000],a[1000];
struct node
{
int ji;
int len;
int add;
};
struct node s[1000];
int dp[110][110][110];
int main ()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
book[a[i]]=1;
}
int cnt1=0,cnt2=0;
for(int i=1;i<=n;i++)
{
if(book[i]==0)
{
if(i%2==1)
{
cnt1++;
}
else
{
cnt2++;
}
}
}
if(cnt1+cnt2==n)
{
if(n==1)
{
cout<<0;
}
else
{
cout<<1;
}
return 0;
}
int pos=1,len=0;
int temp=0;
while(a[pos]==0)
{
temp++;
pos++;
}
int pos1=pos;
if(temp)
{
len++;
s[len].ji=a[pos]%2;
s[len].len=pos-1;
s[len].add=1;
}
pos=n,temp=0;
while(a[pos]==0)
{
temp++;
pos--;
}
int pos2=pos;
if(temp)
{
len++;
s[len].ji=a[pos]%2;
s[len].len=n-pos;
s[len].add=1;
}
int yu=0,fuckcnt=0;
for(int i=1;i<=n;i++)
{
if(a[i]!=a[i+1])
{
if(a[i]!=0&&a[i+1]!=0)
{
if(a[i]%2!=a[i+1]%2)
yu++;
}
}
}
for(int i=pos1;i<pos2;i++)
{
if(a[i]&&a[i+1]==0)
{
//分段
int tempcnt=0;
for(int j=i+1;j<pos2;j++)
{
if(a[j]==0)
tempcnt++;
else
break;
}
int nex=i+tempcnt+1;
if(a[nex]%2!=a[i]%2)
{
fuckcnt+=tempcnt;
yu++;
}
else
{
len++;
s[len].ji=a[nex]%2;
s[len].len=tempcnt;
s[len].add=2;
}
i=nex-1;
}
}
// 前i段耗费多少cnt1,多少cnt2,得到的最小值
for(int i=0;i<=n;i++)
{
for(int j=0;j<=n;j++)
{
for(int k=0;k<=n;k++)
{
dp[i][j][k]=1e9;
}
}
}
dp[0][0][0]=0;
for(int i=1;i<=len;i++)
{
for(int j=0;j<=cnt1;j++)
{
for(int k=0;k<=cnt2;k++)
{
for(int now1=0;now1<=j;now1++)
{
//枚举我当前使用了多少1
int now2=s[i].len-now1;
//枚举我当前用了多少2
if(now2>k||now2<0)
continue;
//不合法
if(s[i].ji==1&now1==s[i].len)
{
dp[i][j][k]=min(dp[i][j][k],dp[i-1][j-now1][k-now2]);
}
else if(s[i].ji==0&&now2==s[i].len)
{
dp[i][j][k]=min(dp[i][j][k],dp[i-1][j-now1][k-now2]);
}
else
{
dp[i][j][k]=min(dp[i][j][k],dp[i-1][j-now1][k-now2]+s[i].add);
}
}
}
}
}
int ans=1e9;
for(int i=0;i<=cnt1;i++)
{
for(int j=0;j<=cnt2;j++)
{
if((i+j)==cnt1+cnt2-fuckcnt)
{
ans=min(ans,dp[len][i][j]);
}
}
}
cout<<ans+yu;
return 0;
}