[CareerCup][Google Interview] K上升序列总和
Given an array of integers, find out number of ways in which you can select increasing subsequences of length k(k<=n).
for eg array is 1 4 6 2 5 & k=3
then the answer is :1 4 5, 1 2 5,1 4 6,
so ways are 5
he first made me to write a recurrence then asked me to memoize that
这题可以用dfs做,但显然耗时是指数级的。这种类似只要找个数而最终不需要打印各种排列结果的就可以想想用DP了。状态转移方程很好写,
f[i][j]表示以第i个数作为序列最后一个数,有j个长度的上升序列个数。f[i][j] = sum(f[k][j-1]), 0<=k<i, 且a[i] > a[k]。
最后sum(f[i][K]), 0 <= i < n就是结果了。复杂度O(n*n*K)
1 #include <iostream> 2 using namespace std; 3 4 int solve(int a[], int size, int K) 5 { 6 int f[100][100]; 7 8 memset(f, 0, sizeof(f)); 9 10 for(int i = 0; i < size; i++) 11 f[i][1] = 1; 12 13 for(int i = 1; i < size; i++) 14 for(int j = 0; j < i; j++) 15 if (a[i] > a[j]) 16 for(int k = 1; k <= K - 1; k++) 17 f[i][k+1] += f[j][k]; 18 19 int sum = 0; 20 for(int i = 0; i < size; i++) 21 sum += f[i][K]; 22 23 return sum; 24 } 25 26 int main() 27 { 28 int a[] = {1, 4, 6, 2, 5}; 29 int K = 3; 30 31 cout << solve(a, sizeof(a) / sizeof(int), K) << endl; 32 }