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 }
时间: 2024-10-13 17:47:40

DP:Miking Time(POJ 3616)的相关文章

Dp Milking Time POJ - 3616

题目大意: 一头奶牛产奶的时间是1-n,农夫有m个时间段可以去收集奶,每次收了奶之后奶牛要休息R时间,求农夫可以收的奶的最大值. 每次自己要想蛮久都想不出怎么去推,还是做的题太少啦...一看题解 知道dp[i]表示区间[1,i]所能得到牛奶的最大值后,一下就写出来啦. 思路类似于求最长递增子序列. #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #includ

POJ 3616 Milking Time DP题解

典型的给出区间任务和效益值,然后求最大效益值的任务取法. 属于一维DP了. 一维table记录的数据含义:到当前任务的截止时间前的最大效益值是多少. 注意, 这表示当前任务一定要选择,但是最终结果是不一定选择最后一个任务,故此最后需要遍历找到table数组的最大值,当然计算过程中使用一个数记录最终最大值也是可以的. 状态转移方程就是: tbl[i] = MAX({from tbl[0]->tbl[i-1] }+ weight[i] ),即区间0到i-1加上i的当前效益值. #include <

R - Milking Time POJ 3616 ( DP )

R - Milking Time Time Limit:1000MS Memory Limit:65536KB 64bit IO Format:%I64d & %I64u Submit Status Practice POJ 3616 Description Bessie is such a hard-working cow. In fact, she is so focused on maximizing her productivity that she decides to schedul

poj 3616 Milking Time dp+树状数组

题意: 给一堆区间,每个区间有开始时间s,结束时间e,和收益w,现在要找一些区间使收益和最大,且区间之间的间隔最小为r. 分析: 这道题用dp做是简单题,用dp+树状数组做是中等题.dp问题的关键是对状态的定义.有两种方法,一:dp[k]表示按开始时间排序到第k个区间能取得的最大收益.二:dp[t]表示在时间t时能获得的最大收益.定义好状态方程就好写了这不再赘述.有趣的是这个时间复杂度.设一共有M个区间,所有区间的最大时间为L,第一种是M^2的,第二种是M*(logL+logM)的,这题M才10

POJ 3616 Milking Time 挤奶问题,带权区间DP

题目链接:POJ 3616 Milking Time Milking Time Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 4837   Accepted: 2034 Description Bessie is such a hard-working cow. In fact, she is so focused on maximizing her productivity that she decides to sc

[2016-03-28][POJ][3616][Milking Time]

时间:2016-03-28 17:27:03 星期一 题目编号:[2016-03-28][POJ][3616][Milking Time] #include <algorithm> #include <cstdio> using namespace std; const int maxm = 1000 + 10; struct Roo{ int l,r,v; bool operator < (const Roo & a)const{ return l < a.l

POJ 3616 Milking Time (排序+dp)

题目链接:http://poj.org/problem?id=3616 有头牛产奶n小时(n<=1000000),但必须在m个时间段内取奶,给定每个时间段的起始时间和结束时间以及取奶质量 且两次取奶之间须间隔r-1个小时,求最大取奶质量 也就是说r = 2时 3分结束取奶,至少在5分才能取. 按照时间排序,dp[i]表示i时段的最大产奶量 1 //#pragma comment(linker, "/STACK:102400000, 102400000") 2 #include &

POJ 3616 Milking Time 简单DP

题目链接:http://poj.org/problem?id=3616 题目大意:M个区间,每个区间一个对应一个效率值-多少升牛奶,区间可能重复,现要求取出来一些区间,要求是区间间隔不能小于R,问所能得到的牛奶量的最大值. 解题思路:决策:当前区间用或者不用.区间个数M≤1000,因此直接双循环递推即可. dp[i]:=选第i个区间情况下前i个区间能获得的牛奶最大值 dp[i] = max(dp[i], dp[j] + a[i].eff) a[j].end + r <= a[i].start 代

POJ 3616 Milking Time 基础DP

Milking Time Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 5743   Accepted: 2401 Description Bessie is such a hard-working cow. In fact, she is so focused on maximizing her productivity that she decides to schedule her next N (1 ≤ N ≤