题目链接

很好的一个dp。

Codeforces Round #522 C-. Playing Piano(巧妙DP)_并查集

Codeforces Round #522 C-. Playing Piano(巧妙DP)_记录路径_02

不错的一篇文章,主要是记录路径这里有点像并查集记录路径。。。。

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10,M=3e5+10;
int a[N],n,b[N],ans[N];
int dp[N][6];
int pre[N][6];
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;++i) scanf("%d",&a[i]);
for(int i=1;i<=5;++i) dp[1][i]=1;

for(int i=2;i<=n;++i)
{
if(a[i]>a[i-1])
{
for(int j=1;j<=5;++j)
for(int k=j+1;k<=5;++k)
{
if(dp[i-1][j])
{
dp[i][k]|=dp[i-1][j];
pre[i][k]=j;
}
}
}
else if(a[i]<a[i-1]){
for(int j=1;j<=5;++j)
for(int k=1;k+1<=j;++k)
{
if(dp[i-1][j])
{
dp[i][k]|=dp[i-1][j];
pre[i][k]=j;
}

}
}
else {
for(int j=1;j<=5;++j)
for(int k=1;k<=5;++k)
{
if(j==k) continue;
if(dp[i-1][j])
{
dp[i][k]|=dp[i-1][j];
pre[i][k]=j;
}
}
}
}

int p=-1;

for(int i=1;i<=5;++i)
{
if(dp[n][i]){
p=i;
break;
}
}

if(p==-1){
printf("-1");
return 0;
}

int len=0;
int j=n;
//ans[++len]=p;
while(p)
{
//printf("j:%d\n",j);
ans[++len]=p;
p=pre[j][p];
--j;
}

for(int i=len;i;--i) printf("%d ",ans[i]);
}