原题位置: https://vijos.org/p/1571
这道题说是个经典DP,但是感觉还好吧,一开始感觉和NOIP花匠是一样的,但是发现自己找不到状态,因为我们要知道当前这个导弹在抽出的序列中的奇偶位置,所以自然而然把原来的状态定义改了,但是还是b[1][i]和b[2][i],但是定义为b[1][i]是i这个位置是基数位置时的最长序列,b[2][i]是i这个位置是偶数位置时的最长序列,那么就有转移方程了;
方程好长,详情见代码吧;
——————————–分阿分啊分割线———————————
#include<iostream>
#include<cstdio>
#include<algorithm>
#define II int
#define R register
#define I 123456
using namespace std;
II n;
II a[I], b[3][I];
int main()
{
scanf("%d",&n);
for(R II i=1;i<=n;i++) scanf("%d",&a[i]);
b[1][1]=0; b[2][1]=1;
// 基数为b[2][i]; 偶数位b[1][i];
// 第一个数一定没办法作偶数位置的;
for(R II i=2;i<=n;i++)
{
for(R II j=1;j<i;j++)
{
if(a[i]>a[j]) {
// i位置比前一位高;
b[2][i]=max(b[1][j]+1,b[2][i]);
// 可以做基数位置; 所以基数位置由前一个最大的偶数位加一得到;
b[1][i]=max(b[1][i],b[1][j]);
} else if(a[i]<a[j]) {
// i比前一位低;
b[1][i]=max(b[1][i],b[2][j]+1);
// 可以做偶数位置; 所以基数位置由前一个最大的基数位加一得到;
b[2][i]=max(b[2][i],b[2][j]);
} else {
// 相等,则继承;
b[1][i]=max(b[1][i],b[1][j]);
b[2][i]=max(b[2][j],b[2][i]);
}
}
}
printf("%d\n",max(b[1][n],b[2][n]));
// 输出大的;
exit(0);
}
—————————–分阿分啊分割线~~~~~~~~~~~~~~~~~
by pretend-fal
END;