http://acm.hdu.edu.cn/showproblem.php?pid=2372
题意:给出n个数,求长度为m的递增子序列的数目。
思路:状态转移方程 dp[i][j] = sum(dp[k][j-1]| k < i &&a[k]<a[i]) 表示前i个元素中长度为j的递增子序列的数目
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #include <stdio.h> 2 #include <string.h> 3 const int N=120; 4 __int64 dp[N][N]; 5 __int64 a[N]; 6 int main() 7 { 8 __int64 n,m; 9 while(~scanf("%I64d%I64d",&n,&m)) 10 { 11 if (n==0&&m==0) 12 break; 13 memset(dp,0,sizeof(dp)); 14 for (int i = 1;i <= n; i++) 15 { 16 scanf("%I64d",&a[i]); 17 dp[i][1] = 1; 18 } 19 for (int i = 2;i <= n; i++) 20 { 21 for (int j = 2;j <= m; j++) 22 { 23 for (int k = 1;k < i; k++) 24 { 25 if (a[k] < a[i]) //前i个数长度为j的递增子序列数目 26 //=(a[i] > a[k]&&k < i)前k个数中长度为j-1的递增子序列数目的和 27 dp[i][j]+=dp[k][j-1]; 28 } 29 } 30 } 31 __int64 ans = 0; 32 for (int i = 1;i <= n; i++) 33 ans+=dp[i][m]; 34 printf("%I64d\n",ans); 35 } 36 return 0; 37 }