82pts求助
查看原帖
82pts求助
1171476
_error404楼主2024/3/7 13:01
#include<bits/stdc++.h>
using namespace std;
int  a[5005],f[5005],g[5005],n,mx;//f是求最大上升子列长度,g是求方案数
vector<int >low;
int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0),cout.tie(0);
    cin>>n;
    for(int i=1;i<=n;++i)cin>>a[i];
    for(int i=1;i<=n;++i){
        int pos=upper_bound(low.begin(),low.end(),a[i],[&](int val,int ele){return ele<=val;})-low.begin();
        if(pos==low.size())low.push_back(a[i]);
        else low[pos]=a[i];
        f[i]=pos+1;
        mx=max(mx,f[i]);
    }
    cout<<mx<<' ';
    g[1]=1;
    unordered_map<int,int>mp;//用于判断当前遍历的是否与之前的重复了,判断标准就是当前位置结尾的数a[i]与f[i]是否在之前出现过,出现过就说明数列一样,不考虑
    for(int i=2;i<=n;++i){
        unordered_set<int>st;//转移时避免相同数列转移了
        if(f[i]==1){
            g[i]=1;continue;
        }
        for(int j=1;j<i;++j){
            if(a[j]>a[i]&&f[j]==f[i]-1&&!st.count(a[j])&&mp[a[i]]!=f[i]){
                g[i]+=g[j];
                st.insert(a[j]);
            } 
        }
        mp[a[i]]=f[i];
    }
    int ans=0;
    for(int i=1;i<=n;++i){
        if(f[i]==mx)ans+=g[i];
    }
    cout<<ans;
    return 0;
}
2024/3/7 13:01
加载中...