1 解题思路
1.1 定义的变量
· 数组h:存储n根木桩的高度
· 数组f:存储每个木桩的最长升序序列的长度
· 数组cs:存储每个木桩的最长升序序列的方案数
· 变量ti:存储比较后最长升序序列的木桩对应的下标
1.2 过程分析
对于h数组中的每个元素hj,做以下操作:
将h[i]和h[1]至h[j-1]之间的元素(下面将这些元素记作h[j])进行比较:
– 若h[k]<=h[j]:
– 判断加入h[i]后,h[i]的最长升子序列是否达到最长,即f[j]+1>f[i],如果是,更新f[i]。并且此时f[i]的方案数cs[i]更新为f[j]的方案数,即 cs[j]=cs[k]。
– 若f[k]+1==f[j],说明第j个元素的最长升子序列加入h[i]后的序列长度可以也达到f[i],又有新的方案,那就cs[j]需要加上cs[k]。
–之后比较一下更新后的方案数,是否大于全部方案中的最大方案数,是就记录下最大升子序列的下标,即ti=j。
2 AC代码
#include<bits/stdc++.h>
using namespace std;
int m;
int h[200],f[200],cs[200];
int main(){
cin>>m;
for(int i=1;i<=m;i++){
int x,ti=1;
memset(h,0,sizeof(h));
memset(f,0,sizeof(f));
cin>>x;
for(int j=1;j<=x;j++){
cin>>h[j];
f[j]=1;
cs[j]=1;
}
for(int j=2;j<=x;j++){
for(int k=1;k<j;k++){
if(h[k]<=h[j]){
if(f[k]+1>f[j]){
f[j] = f[k]+1;
cs[j]=cs[k];
}
else if(f[k]+1==f[j]){
cs[j]+=cs[k];
}
if(f[k]+1>f[ti])
ti=j;
}
}
}
cout<<f[ti]<<" "<<cs[ti]<<endl;
}
return 0;
}