题意:长度为n的序列a,问有多少个长度为k的递增子序列? n<=100,a[i]<=1e9.
dp[i][j]:第i个数结尾 长度为j的子序列个数 O(n^3).
dp[i][j]:第i个数结尾 长度为j的子序列个数 O(n^3).
答案最大为C(n,k) 会爆long long 用高进度加
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e2+5,mod=1e8;
struct Bigint{
int len,p[N];
Bigint()
{
memset(p,0,sizeof(p));
len=0;
}
}dp[N][N],ans;
ll n,k,a[N];
Bigint add(const Bigint &x,const Bigint &y)
{
Bigint cnt;
int t=max(x.len,y.len);
for(int i=1;i<=t;i++)
{
cnt.p[i]+=x.p[i]+y.p[i];
cnt.p[i+1]=cnt.p[i]/mod;//节约内存 第i个存(1e8)^i的数
cnt.p[i]%=mod;
}
if(cnt.p[t+1])
t++;
cnt.len=t;
return cnt;
}
void print(const Bigint& x)
{
printf("%d",x.p[x.len]);
for(int i=x.len-1;i>=1;i--)
printf("%08d",x.p[i]);
printf("\n");
}
int main()
{
while(cin>>n>>k)
{
for(int i=1;i<=n;i++)
cin>>a[i];
memset(dp,0,sizeof(dp));
memset(ans.p,0,sizeof(ans.p));
ans.len=1;
for(int i=1;i<=n;i++)
{
dp[i][1].len=dp[i][1].p[1]=1;
for(int j=2;j<=k;j++)
{
for(int p=1;p<i;p++)
{
if(a[i]<=a[p])
continue;
dp[i][j]=add(dp[i][j],dp[p][j-1]);
}
}
ans=add(ans,dp[i][k]);
}
print(ans);
}
return 0;
}