POJ 1042 Gone Fishing
Title Requirements:
By the N lakes, in order, a person travels from the first lake to the last lake (the direction is only from Lake 0 to Lake N-1) and can be fished in the lake on the way. When fishing in each lake, the first 5 minutes to catch the f[i] bar, after 5 minutes to catch the number of fish d[i], and every two adjacent lake T[i] given (T[i) said from the lake I to 1 Lakes travel on the road to spend a multiple of 5 minutes, that is, if t[3] = 4, it takes 20 minutes to travel from a third lake to a fourth lake. Now given the total time H hours, to find out at each lake fishing time of the best scheme, so that the total number of fishing, if the two scenarios result in the same, then output in the smaller number of lakes fishing time more of that.
Topic Analysis:
Optimization problem, can choose dynamic programming or greedy algorithm, at first glance, is a multi-stage decision-making problem, and each stage will have an impact on the next stage, and do not find the right greedy strategy, more suitable for dynamic planning. First consider the dynamic programming algorithm, you can consider the motion-gauge array dp[t][n] to indicate the optimal value of the fishing results before the T-moment arrives at Lake N, you can find the recursive relationship dp[t][n] = max{dp[t1][n-1] + fish_result (n-1, T-t1- T[n-1])}
That is, the time to reach the lake N-1 T1 enumeration (within a certain range, less than t-t[n-1], greater than XX), and then remove the maximum value as dp[t][n], so from N-1 to N.
Personally, this method of dynamic planning is feasible, but. Because the level is too vegetable. No success.
Consider the use of greedy algorithm to achieve, careful analysis, when the number of lakes to determine the need to reach N, also determine the time required to consume on the road, so that the total time to get fishing, so in the specified time fishing, each time the current 5 minutes to choose the most profitable lake fishing (you can use priority queue Priority_queue to implement). Considering that it is possible to go fishing in Lake a first, then fishing in Lake B and then back to lake a for fishing ... But this does not affect the final result (which is the premise that the greedy algorithm can apply to this problem). Because, although only from Lake 0 to Lake N-1 March, at this time greedy choice although the order of each selection may be reversed change, but this is only to determine how many times lake A has been selected fishing, that is, to determine the lake 0 to Lake n-1 each lake fishing time. When fishing in the real way, just follow the greedy scheme (fishing several times in Lake I), fishing in the lake on the way.
By fixing the number of lakes to pass N, each lake due to the difference in time spent on the road to remove, making the choice to face no difference, you can use the greedy algorithm.
Implementation code:
#include <iostream> #include <stdio.h> #include <string.h> #include <queue> #include <vector >using namespace std; #define Max_interval_num 200#define max_lake_num 25int dist_time[max_lake_num];int min_dist_ Time[max_lake_num];int Stay_times[max_lake_num];int Init_num[max_lake_num];int dec_num[MAX_LAKE_NUM];struct lakenode{int lake_index; int cur_fish_amount; int dec_amount; int stay_time;}; Lakenode lake_nodes[max_lake_num];struct cmp{bool Operator (lakenode* lake1, lakenode* lake2) {if (lake1-> Cur_fish_amount = = Lake2->cur_fish_amount) {return lake1->lake_index > lake2->lake_index; } return Lake1->cur_fish_amount < lake2->cur_fish_amount; }};void Clearqueue (priority_queue<lakenode*, vector<lakenode*>, cmp>& queue) {while (! Queue.empty ()) {Queue.pop (); }}int Resolve (int N, int T) {priority_queue<lakenode*, vector<lakenode*>, cmp> Lake_queue; LakEnode* Lake; int result = 0, Max_amount = 0; Stay_times[0] = T; for (int n = 1; n <= N; n + +) {result = 0; int fish_time = t-min_dist_time[n-1]; if (fish_time <= 0) {break; } clearqueue (Lake_queue); for (int i = 0; i < n; i + +) {lake_nodes[i].stay_time = 0; Lake_nodes[i].lake_index = i; Lake_nodes[i].cur_fish_amount = Init_num[i]; Lake_nodes[i].dec_amount = Dec_num[i]; Lake_queue.push ((lakenode*) &lake_nodes[i]); } while (! Lake_queue.empty () && fish_time > 0) {lake = Lake_queue.top (); Lake_queue.pop (); if (Lake->cur_fish_amount > 0) {result + = lake->cur_fish_amount; Lake->cur_fish_amount-= lake->dec_amount; } if (Lake->cur_fish_amount <= 0) {lake->cur_fish_amount = 0; } Lake->stay_time + +; Fish_time--; Lake_queue.push (lake); } if (Result > Max_amount) {max_amount = result; for (int i = 0; i < n; i + +) {Stay_times[i] = Lake_nodes[i].stay_time; }}} return max_amount;} int main () {int n, h; while (true) {cin >> n; if (n = = 0) {break; } cin >> H; h = h*12; for (int i = 0; i < n; i + +) {cin >> init_num[i]; Stay_times[i] = 0; } for (int i = 0; i < n; i + +) {cin >> dec_num[i]; } Min_dist_time[0] = 0; CIN >> Dist_time[0]; for (int i = 1; i < n-1; i + +) {cin >> dist_time[i]; Min_dist_time[i] = Min_dist_time[i-1] + dist_time[i-1]; } min_dist_time[n-1] = Min_dist_time[n-2] + dist_time[n-2]; int result = Resolve (n, h); cout << stay_times[0]*5; for (int i = 1; i < n; i + +) {cout << "," << stay_times[i]*5; } cout << Endl << "Number of fish expected:" << result << Endl << Endl; } return 0;}
Greedy algorithm--gone fishing