標籤:
題意比較簡單,
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\n", ans);63 }64 return 0;65 }
HDU5406---CRB and Apple( DP) 2015 Multi-University Training Contest 10