http://poj.org/problem?id=1042
题目大意:约翰要去钓鱼。他有h小时可用(1 <= h <= 16),该区域有n个湖泊(2 <= n <= 25),可沿着一条单行道到达。约翰从1号湖出发,但他可以在任何他想要的湖结束。他只能从一个湖到另一个湖,但他不需要在任何一个湖停下来,除非他愿意。对于每个i = 1,…n - 1,从i湖到湖i + 1的5分钟间隔为ti (0 < ti <=192)。例如,t3 = 4意味着从3湖到4湖需要20分钟。为了帮助计划他的钓鱼之旅,约翰收集了一些关于湖泊的信息。对于每个湖i,预计在初始5分钟内捕获的鱼的数量,表示fi(fi >= 0),已知。每5分钟的捕鱼减少了预期在接下来的5分钟内捕获的鱼的数量(di >= 0)。如果预期在间隔内捕获的鱼数量少于或等于di,那么在下一段时间内将不再有鱼留在湖中。为了简化计划,约翰假设没有人会在湖边钓鱼,以影响他想钓到的鱼的数量。
编写一个程序,帮助John计划他的钓鱼之旅,以最大限度地捕获被捕获的鱼的数量。在每个湖上花费的分钟数必须是5的倍数。
也就是说,John要钓到最多的鱼,但是有n个湖,在湖之间位移还需要时间,所以John可能有n种最终停下的位置,我们要去比较这n种情况的钓鱼总数,选出最大的,再输出结果。为了方便表示,我们可以采取碎片化钓鱼,首先把总时间减去走到第p(p<=n)所需要的时间,那么剩余时间都是用来钓鱼的时间,假设John可以瞬间位移,John每次选择剩余最多鱼的湖去钓鱼,这样钓鱼的数目才会达到最多。当然John肯定不会瞬间位移啦,不过没关系,由碎片化钓鱼转化为整体化钓鱼即可。
算法思想:贪心算法,由于John可能在n个湖的任一个位置停下,所以我们要考虑n种情况,并选择出钓鱼总数最多的那种情况。每一种情况都贪心去能钓到最多鱼的湖去钓鱼,若全部鱼都钓完了,就待在第一个湖(案例就是这样)。显然每一次贪心我们要去比较,选出剩余的鱼最多的湖钓鱼,钓完后,相应的期望钓鱼数减少。
#include <iostream> #include <xmemory> #include <climits> #define N 25 using namespace std; int main(void) { int n, h; int fi[N], di[N], ti[N];//fi[]期望钓鱼数, di[]每五分钟减少鱼数, ti[]位移时间 int time[N];//在当前湖停下来时在每个湖停留的时间 int best[N];//最优解对应的在每个湖停留的时间 int bestFishNum;//最优解钓鱼总数 int fishNum;//当前钓鱼总数 while (cin >> n && n) { cin >> h; h *= 12;//共有h个5分钟 for (int i = 0; i < n; i++) cin >> fi[i];//期望钓鱼数 for (int i = 0; i < n; i++) cin >> di[i];//每五分钟减少鱼数 for (int i = 0; i < n - 1; i++) cin >> ti[i];//位移时间 bestFishNum = INT_MIN; memset(best , 0 , sizeof best); for (int p = 0; p < n; p++) {//穷举最终停下的湖的位置 memset(time , 0 , sizeof(time)); fishNum = 0; int remainingTime = h;//当前剩余时间 int remainingFish[N];//当前在每个湖剩余能钓的鱼的数目 for (int i = 0; i < n; i++) remainingFish[i] = fi[i];//初始化 for (int j = 0; j < p; j++) remainingTime -= ti[j];//先减去路程,之后假设John可以在lake 0到lake i之间随意位移 while (remainingTime > 0) {//直到时间用尽 int max = INT_MIN; int pos = 0;//当前能钓鱼最多的位置 for (int j = 0; j <= p; j++)//每次选出能钓鱼最多的位置 if (remainingFish[j] > max) { max = remainingFish[j]; pos = j;//找到位置 } time[pos]++;//对应时间++ fishNum += remainingFish[pos];//累加钓鱼数 remainingFish[pos] =remainingFish[pos]- di[pos]>0?remainingFish[pos]-di[pos]:0; remainingTime--; } if (fishNum > bestFishNum) { bestFishNum = fishNum; for (int i = 0; i < n; i++) { best[i] = time[i]; } } } for (int i = 0; i < n - 1; i++) cout << best[i] * 5 << ", "; cout << best[n - 1] * 5 << endl;//注意输出格式 cout << "Number of fish expected: " << bestFishNum << endl << endl; } return 0; }