挺好的一道DP。
1 /* 2217 */ 2 #include <iostream> 3 #include <cstdio> 4 #include <cstring> 5 #include <cstdlib> 6 #include <algorithm> 7 using namespace std; 8 9 #define MAXN 2005 10 #define MAXM 100005 11 12 int lt[MAXN], rt[MAXN]; 13 int ldp[MAXM], rdp[MAXM]; 14 int ln, rn, zn; 15 16 int main() { 17 int n, t; 18 int i, j, k, tmp; 19 int ans; 20 21 #ifndef ONLINE_JUDGE 22 freopen("data.in", "r", stdin); 23 #endif 24 25 while (scanf("%d %d", &n, &t) != EOF) { 26 ln = rn = 1; 27 zn = 0; 28 lt[0] = 0; 29 rt[0] = 0; 30 for (i=0; i<n; ++i) { 31 scanf("%d", &k); 32 if (k > 0) 33 rt[rn++] = k; 34 else if (k < 0) 35 lt[ln++] = -k; 36 else 37 ++zn; 38 } 39 40 rt[0] = 0; 41 lt[0] = 0; 42 sort(rt, rt+rn); 43 sort(lt, lt+ln); 44 ldp[0] = 0; 45 rdp[0] = 0; 46 47 k = 0; 48 for (i=1; i<ln; ++i) { 49 for (j=lt[i-1]; j<lt[i]; ++j) 50 ldp[j] = k; 51 ++k; 52 ldp[j] = k; 53 } 54 55 k = 0; 56 for (i=1; i<rn; ++i) { 57 for (j=rt[i-1]; j<rt[i]; ++j) 58 rdp[j] = k; 59 ++k; 60 rdp[j] = k; 61 } 62 63 ans = -1; 64 // go left and back to right 65 for (i=0; i<=lt[ln-1]; ++i) { 66 if (t < i) 67 break; 68 k = t-(i+i); 69 if (k < 0) 70 k = 0; 71 if (k > rt[rn-1]) 72 k = rt[rn-1]; 73 74 ans = max(ans, ldp[i]+rdp[k]); 75 } 76 // go right and back to left 77 for (i=0; i<=rt[rn-1]; ++i) { 78 if (t < i) 79 break; 80 k = t-(i+i); 81 if (k < 0) 82 k = 0; 83 if (k > lt[ln-1]) 84 k = lt[ln-1]; 85 86 ans = max(ans, rdp[i]+ldp[k]); 87 } 88 // go zero point first 89 ans += zn; 90 91 printf("%d ", ans); 92 } 93 94 return 0; 95 }