思路:题目很明显是lis的拓展,重要的是重复方案的处理。
核心代码即:
for(int i=1;i<=n;i++)
{
if(dp[i]==1) t[i]=1; //对处于lis序列标记
for(int j=1;j<i;j++)
if(a[i]>a[j]&&dp[i]==dp[j]+1) t[i]+=t[j];
//对于同一Lis序列,t数组递增。
else if(a[i]==a[j]&&dp[i]==dp[j]) t[i]=0;
//对于相同数字且lis答案相同的就清除。
}
完整代码如下:
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int N=5e3+10;
int dp[N],t[N];
int n,a[N];
int cnt,ans=1;
int main()
{
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i],dp[i]=1;
reverse(a+1,a+1+n);
for(int i=1;i<=n;i++)
for(int j=1;j<i;j++)
if(a[i]>a[j])
{
dp[i]=max(dp[i],dp[j]+1);
ans=max(ans,dp[i]);
}
cout<<ans<<" ";
int x=-1;
for(int i=1;i<=n;i++)
{
if(dp[i]==1) t[i]=1;
for(int j=1;j<i;j++)
if(a[i]>a[j]&&dp[i]==dp[j]+1) t[i]+=t[j];
else if(a[i]==a[j]&&dp[i]==dp[j]) t[i]=0;
}
for(int i=1;i<=n;i++) if(dp[i]==ans) cnt+=t[i];
cout<<cnt<<endl;
return 0;
}