hdu 2372 El Dorado(dp)

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;
}



你可能感兴趣的:(dp)