http://acm.hdu.edu.cn/showproblem.php?pid=2372
题意:给一个序列,求长度为k的递增子序列的个数。
思路:开始敲的最长上升子序列模板加组合数学,无限WA,是由于n太大了(100)。后来看了看解题报告。
dp[ i ][ j ] 表示以i结尾的长度为j 的最多子串个数.
dp[i][j] += dp[g][j-1] (其中 j-1 <= g <= i && a[g] < a[i])
#include <stdio.h>
#include <string.h>
#include <algorithm>
#define LL __int64
using namespace std;
int main()
{
int n,k;
int a[110];
LL dp[110][110],ans;
while(~scanf("%d %d",&n,&k))
{
if(!n && !k) break;
memset(dp,0,sizeof(dp));
for(int i = 1; i <= n; i++)
{
scanf("%d",&a[i]);
dp[i][1] = 1;
}
ans = 0;
for(int i = 1; i <= n; i++) //以i结尾
{
for(int j = 1; j <= i; j++) //长度为j的上升子序列由长度为j-1的上升子序列求出
{
for(int g = j-1; g < i; g++)//枚举长度为j-1的上升子序列的终点
{
if(a[g] < a[i])
dp[i][j] += dp[g][j-1];
}
}
}
for(int i = 1; i <= n; i++)//最后要将所有 上升子序列长度为k的相加
ans += dp[i][k];
printf("%I64d\n",ans);
}
return 0;
}