A. Garland
题目链接-Garland
题目大意
给你1-n个数的乱序排列,有些位置上的数为0(即该位置为空),如何用剩下的数填充这个序列,使得相邻灯泡奇偶对数最小
解题思路
四维数组线性DP
一维:长度
二维:奇数的个数
三维:偶数的个数
四维:奇偶性
附上代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int INF=0x3f3f3f;
const int N=105;
int f[N][N][N][2];
int a[N],sum[N];
int main(){
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
int n;
cin>>n;
int odd=n-n/2,even=n/2;
for(int i=1;i<=n;i++){
cin>>a[i];
if(a[i]){
if(a[i]&1) odd--;
else even--;
}
else
sum[i]++;
}
memset(f,INF,sizeof f);
for(int i=1;i<=n;i++)
sum[i]+=sum[i-1];
if(a[1]){
if(a[1]&1) f[1][0][0][1]=0;
else f[1][0][0][0]=0;
}
else{
f[1][1][0][1]=0;
f[1][0][1][0]=0;
}
for(int i=2;i<=n;i++){
for(int j=0;j<=odd;j++){
int k=sum[i]-j;
if(k>sum[i]||j>sum[i]||k<0)
continue;
else{
if(a[i]){
if(a[i]&1)
f[i][j][k][1]=min(f[i-1][j][k][0]+1,f[i-1][j][k][1]);
else
f[i][j][k][0]=min(f[i-1][j][k][1]+1,f[i-1][j][k][0]);
}
else{
if(j) f[i][j][k][1]=min(f[i-1][j-1][k][0]+1,f[i-1][j-1][k][1]);
if(k) f[i][j][k][0]=min(f[i-1][j][k-1][1]+1,f[i-1][j][k-1][0]);
}
}
}
}
int ans=0;
if(a[n]){
if(a[n]&1)
ans=f[n][odd][even][1];
else
ans=f[n][odd][even][0];
}
else
ans=min(f[n][odd][even][0],f[n][odd][even][1]);
cout<<ans<<endl;
return 0;
}