题目链接:
http://www.lydsy.com/JudgeOnline/problem.php?id=1609
题解:
dp,用dp[i][k]表示前i个数中结尾为k时的最小代价,那么很明显,有递推:
f[i][3]=m(f[i-1][3],f[i-1][2],f[i-1][1])+1;
f[i][2]=min(f[i-1][2],f[i-1][1])+1;
f[i][1]=f[i-1][1]+1;
f[i][a[i]]--;
g[i][3]=g[i-1][3]+1;
g[i][2]=min(g[i-1][3],g[i-1][2])+1;
g[i][1]=m(g[i-1][3],g[i-1][2],g[i-1][1])+1;
g[i][a[i]]--;
f表示数列为递减的时候,g表示数列为递增的时候
代码:
#include<iostream>
#include<algorithm>
#include<stdio.h>
#define maxn (30005)
using namespace std;
int n,f[maxn][4],g[maxn][4],a[maxn];
int m(int x,int y,int z)
{
return min(min(x,y),z);
}
int main()
{
scanf("%d",&n);
for (int i=1;i<=n;i++)
scanf("%d",&a[i]);
for (int i=1;i<=n;i++)
{
f[i][3]=m(f[i-1][3],f[i-1][2],f[i-1][1])+1;
f[i][2]=min(f[i-1][2],f[i-1][1])+1;
f[i][1]=f[i-1][1]+1;
f[i][a[i]]--;
g[i][3]=g[i-1][3]+1;
g[i][2]=min(g[i-1][3],g[i-1][2])+1;
g[i][1]=m(g[i-1][3],g[i-1][2],g[i-1][1])+1;
g[i][a[i]]--;
}
int ans=min(m(g[n][3],g[n][2],g[n][1]),m(f[n][3],f[n][2],f[n][1]));
printf("%d\n",ans);
}