DP:Miking Time(POJ 3616)
2015-09-21
题目大意就是这只Bessie的牛产奶很勤奋,某农民有一个时刻表,在N时间内分成M个时间段,每个时间段Bessie会一直产奶,然后有一定的效益,并且Bessie产奶后要休息两个小时。
这是一道很简答的DP,因为区间是不重复的,所以我们只要快排一下就好了,然后从第一个时间段到最后一个时间段
状态转移方程:
dp[i][j]=dp[i-1][j] j<i;
dp[i][i]=MAX(dp[i][i],dp[i][j]+list[i].eff); j<i
很简单是吧,我这道题做了两个小时????
为什么???因为我快排写错了!
代码一开始交的时候是1001*1001矩阵,时间是0ms,但是内存要用到7000+,用滚动数组时间到16ms,但是内存变成了132,还是值得的
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 #define MAX(a,b) (a)>(b)?(a):(b) 5 #define CUTOFF 20 6 7 typedef int Position; 8 typedef struct input 9 { 10 int start_hour; 11 int end_hour; 12 int eff; 13 }LIST; 14 15 LIST list[1000]; 16 long long dp1[1001]; 17 long long dp2[1001]; 18 19 void Quick_Sort(Position, Position); 20 void Swap(Position, Position); 21 void Insertion_Sort(Position, Position); 22 int Median_Of_Three(Position, Position, Position); 23 void Search(const int, const int, const int); 24 25 int main(void) 26 { 27 int interval, R, N, i; 28 29 while (~scanf("%d%d%d", &N, &interval, &R)) 30 { 31 for (i = 1; i <= interval; i++) 32 scanf("%d%d%d", &list[i].start_hour, &list[i].end_hour, &list[i].eff); 33 list[0].start_hour = INT_MIN; list[0].end_hour = -R; 34 Quick_Sort(1, interval); 35 Search(N, interval, R); 36 } 37 return 0; 38 } 39 40 int Median_Of_Three(Position left, Position middle, Position right) 41 { 42 if (list[left].start_hour > list[middle].start_hour) 43 Swap(left, middle); 44 if (list[left].start_hour > list[right].start_hour) 45 Swap(left, right); 46 if (list[middle].start_hour > list[right].start_hour) 47 Swap(middle, right); 48 Swap(middle, right);//隐藏枢纽元 49 return list[right].start_hour; 50 } 51 52 void Swap(Position x, Position y) 53 { 54 list[x].start_hour ^= list[y].start_hour; 55 list[y].start_hour ^= list[x].start_hour; 56 list[x].start_hour ^= list[y].start_hour; 57 58 list[x].end_hour ^= list[y].end_hour; 59 list[y].end_hour ^= list[x].end_hour; 60 list[x].end_hour ^= list[y].end_hour; 61 62 list[x].eff ^= list[y].eff; 63 list[y].eff ^= list[x].eff; 64 list[x].eff ^= list[y].eff; 65 } 66 67 void Insertion_Sort(Position left, Position right) 68 { 69 Position i, j; 70 int tmp_s, tmp_e, tmp_eff; 71 for (i = left + 1; i <= right; i++) 72 { 73 tmp_s = list[i].start_hour; 74 tmp_e = list[i].end_hour; 75 tmp_eff = list[i].eff; 76 for (j = i; j > left && list[j - 1].start_hour > tmp_s; j--) 77 { 78 list[j].start_hour = list[j - 1].start_hour; 79 list[j].end_hour = list[j - 1].end_hour; 80 list[j].eff = list[j - 1].eff; 81 } 82 list[j].start_hour = tmp_s; 83 list[j].end_hour = tmp_e; 84 list[j].eff = tmp_eff; 85 } 86 } 87 88 void Quick_Sort(Position left, Position right) 89 { 90 Position mid = (left + right) / 2, i, j; 91 int pivot; 92 93 if (right - left > CUTOFF) 94 { 95 pivot = Median_Of_Three(left, mid, right); 96 i = left; j = right; 97 while (1) 98 { 99 while (list[++i].start_hour < pivot); 100 while (list[--j].start_hour > pivot); 101 if (i < j) 102 Swap(i, j); 103 else break; 104 } 105 Swap(i, right); 106 Quick_Sort(left, i - 1); 107 Quick_Sort(i + 1, right); 108 } 109 else Insertion_Sort(left, right); 110 } 111 112 void Search(const int N, const int interval, const int R) 113 { 114 int i, j; 115 long long ans = -1; 116 long long *now = dp2, *prev = dp1, *tmp = NULL; 117 118 for (i = 1; i <= interval; i++) 119 { 120 for (j = i - 1; j >= 0; j--) 121 { 122 now[j] = prev[j]; 123 if (list[i].start_hour - list[j].end_hour >= R) 124 now[i] = MAX(now[i], now[j] + list[i].eff); 125 ans = MAX(ans, now[i]); 126 } 127 tmp = now; now = prev; prev = tmp; 128 } 129 printf("%lld\n", ans); 130 }