題意:ios
有一個數組,包含亂序1-n的元素,而且有些數被從數組中拿出,如今問怎樣將這些數放回才能使,相鄰兩數爲奇偶的對數最小數組
思路:spa
定義dp[i][j][k]爲到n這個位置放了j個偶數最後一位爲奇數或偶數code
那麼轉移方程爲:blog
令t=dp[i-1][j][k]string
i.奇數:dp[i][j][1]=max(dp[i][j][1],t+(k!=1))it
ii.偶數:dp[i][j+1][0]=max(dp[i][j][0],t+(k!=0))io
#include<iostream> #include<algorithm> #include<cstring> #define inf 0x3f3f3f3f using namespace std; const int maxn=110; int dp[maxn][maxn][3],a[maxn],n; int main() { int n,num=0; scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&a[i]); num=n/2; memset(dp,inf,sizeof(dp)); dp[0][0][0]=dp[0][0][1]=0; for(int i=1;i<=n;i++){ for(int j=0;j<i;j++){ for(int k=0;k<2;k++){ int t=dp[i-1][j][k]; if(a[i]){ if(a[i]%2) dp[i][j][1]=min(dp[i][j][1],t+(k!=1)); else dp[i][j+1][0]=min(dp[i][j+1][0],t+(k!=0)); } else{ for(int l=0;l<2;l++) dp[i][j+1-l][l]=min(dp[i][j+1-l][l],t+(l!=k)); } } } } printf("%d\n", min(dp[n][num][0], dp[n][num][1])); }