题目中的要求构成V字形其实隐含着要求两个最大上升子序列
因此可以枚举下标为1-(N-1)的点,分别对两边求最大子序列,最后统计要拿走的书并做出判断是否可以构成V字形
总的来说是一道基础DP的变式
#include<iostream>
#include<cstring>
using namespace std;
int dp1[105],dp2[105];
int ax[105];
int main()
{
int T;
cin>>T;
while(T--)
{
int N,flag1=0,flag2=0,cnt=100000;
cin>>N;
for(int i=0;i<N;i++)
{
cin>>ax[i];
dp1[i]=dp2[i]=1;
}
for(int j=1;j<N-1;j++)
{
for(int i=0;i<N;i++)
dp1[i]=dp2[i]=1;
int cnt1=0,cnt2=0;
for(int i=j;i>=0;i--)//求左边的最大上升子序列
{
for(int k=i-1;k>=0;k--)
{
if(ax[i]<ax[k])
{
flag1=1;
dp1[k]=max(dp1[k],dp1[i]+1);
}
cnt1=max(dp1[k],cnt1);
}
}
for(int k=j;k<=N-1;k++)//求右边的
{
for(int i=k+1;i<=N-1;i++)
{
if(ax[k]<ax[i])
{
flag2=1;
dp2[i]=max(dp2[i],dp2[k]+1);
}
cnt2=max(dp2[i],cnt2);
}
}
cnt=min(N-(cnt1+cnt2-1),cnt);//求值
}
if(flag1&&flag2)
{
cout<<"HAPPY"<<endl;
cout<<cnt<<endl;
}
else
cout<<"SAD"<<endl;
}
return 0;
}