题意比较简单,
dp[i][j] 表示上一次男女吃的deliciousness分别为i, j的时候的吃的最多的苹果。
那么dp[i][j] = max(dp[i][k] + 1), 0 < k <= j
dp[i][j] = max( max(dp[k][j]) + 1 ) , 0 < k <= i
对于第一个式子最大值 用树状数组线段树都可以解决, 第二个式子如果每次从0遍历到i再找最值的话,显然会超时。
仔细想想便可以发现第二个最值和第一个是一样的。 这个不好解释。 像是对称性那种 一样。
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int MAXN = 1001; 4 struct Node{ 5 int h, d; 6 bool operator < (const Node &rhs)const{ 7 return h != rhs.h ? h > rhs.h : d < rhs.d; 8 } 9 }apple[MAXN]; 10 int arr[MAXN<<1][MAXN<<1]; 11 int MAX; 12 inline int lowbit (int x){ 13 return x & -x; 14 } 15 void Modify (int x, int y, int d){ 16 while (y < MAX){ 17 arr[x][y] = max(arr[x][y], d); 18 y += lowbit(y); 19 } 20 } 21 int query (int x, int y){ 22 int res = 0; 23 while (y){ 24 res = max(arr[x][y], res); 25 y -= lowbit(y); 26 } 27 return res; 28 } 29 int lsh[MAXN << 1], lshtot, tmp[MAXN << 1]; 30 int main() 31 { 32 int T, n; 33 scanf ("%d", &T); 34 while (T--){ 35 scanf ("%d", &n); 36 lshtot = 0; 37 for (int i = 0; i < n; i++){ 38 scanf ("%d%d", &apple[i].h, &apple[i].d); 39 lsh[lshtot++] = apple[i].d; 40 } 41 sort (apple, apple+n); 42 sort (lsh, lsh+lshtot); 43 lshtot = unique(lsh, lsh+lshtot) - lsh; 44 for (int i = 0; i < n; i++){ 45 apple[i].d = lower_bound(lsh, lsh+lshtot, apple[i].d) - lsh + 2; 46 } 47 MAX = lshtot + 5; 48 memset(arr, 0, sizeof (arr)); 49 for (int i = 0; i < n; i++){ 50 for (int j = 2; j <= lshtot+1; j++){ 51 tmp[j] = query(j, apple[i].d); 52 } 53 for (int j = 2; j <= lshtot+1; j++){ 54 Modify(apple[i].d, j, tmp[j]+1); 55 Modify(j, apple[i].d, tmp[j]+1); 56 } 57 } 58 int ans = 0; 59 for (int i = 1; i <= lshtot+1; i++){ 60 ans = max(ans, query(i, lshtot+1)); 61 } 62 printf("%d ", ans); 63 } 64 return 0; 65 }