OpenJudge Gone Fishing
故事背景
约翰要去钓鱼。他有h小时(比如5小时),附近有n个湖(比如3个湖),这些湖在一条单行路上,顺序是:湖i(i为1到n)。
规则
只能往前走:从湖1出发,可以去湖2、湖3...但不能回头。可以随时停下来结束行程。
路上花时间:从湖i到湖i+1需要 t[i] 个"5分钟"(比如 t[2]=4 表示从湖2到湖3要走20分钟)
钓鱼:
在湖i,第一个5分钟能钓 f[i] 条鱼
每多钓5分钟,这个湖的鱼量就减少 d[i] 条
如果鱼量 ≤ d[i],下一周期就没鱼了(变成0)
只能整5分钟地钓:不能钓3分钟、7分钟,必须是5分钟的倍数
目标
怎么安排:
在哪个湖停多久
什么时候移动到下一个湖
才能让总共钓到的鱼最多?
为什么我提交后是WA,实在不知道哪里有问题
#include <iostream>
#include <queue>
#include <vector>
#include<algorithm>
using namespace std;
struct fish {
int i;//第i个湖
int j;//第j个时间片
int f;//能钓到的鱼
// 用于排序:按鱼数从大到小
bool operator < (const fish & other) const {
return f > other.f; }
};
struct ans_out {
int stay[26] = { 0 };//每个湖的停留时间,输出的时候需要将时间片进行换算
int f=0;//钓到的鱼的数目
// 修改比较函数:先比鱼数,再比停留时间
bool operator < (const ans_out& other) const {
if (f != other.f)
return f > other.f; // 鱼数大的优先
// 鱼数相同,按题目要求:尽可能在湖1待久,然后湖2...
for (int i = 1; i <= 25; i++) {
if (stay[i] != other.stay[i]) {
return stay[i] > other.stay[i]; // 停留时间长的优先
}
}
return false; // 完全相同时,谁排在前面都一样
}
};
int main() {
int n, k;
while (cin >> n >> k) {
if (n == 0)break;
k = k * 12;
int fi[26], di[26], ti[26];//ti表示湖i到湖i+1花费的时间
for (int i = 1; i <= n; i++)cin >> fi[i];
for (int i = 1; i <= n; i++)cin >> di[i];
for (int i = 1; i < n; i++)cin >> ti[i];
//预处理,生成在要求时间片下可能用到的每个湖各个时间片的鱼
vector<fish> ve;
for (int i = 1; i <= n; i++) {
int f = fi[i];
int d = di[i];
int j = 0;//代表这个湖的第几个时间片
while (j < k && f > 0) {//只处理必要的时间片
j++;
ve.push_back({ i,j,f });
f -= d;
}
}
sort(ve.begin(), ve.end());
//枚举可能停下的湖
ans_out ans_possible[26];
int start, end;
for (end = 1; end <= n; end++) {
//计算出剩余的钓鱼时间片的数量
int k1 = k;
for (start = 1; start < end; start++)k1 -= ti[start];
if (k1 <= 0) {//时间片不足
ans_possible[end].f = -1;
continue;
}
//应该选择前 k1 个鱼最多的、且湖编号 ≤ end 的时间片
int selected = 0;
for (int idx = 0; idx < ve.size() && selected < k1; idx++) {
if (ve[idx].i <= end) { // 只考虑终点湖及之前的湖
ans_possible[end].stay[ve[idx].i] += 5; // 累加分钟数
ans_possible[end].f += ve[idx].f;
selected++;
}
}
//如果时间片多余则直接添加到第一个湖
while (selected < k1) {
ans_possible[end].stay[1] += 5;
selected++;
}
}
//输出答案
sort(ans_possible + 1, ans_possible + n + 1);
ans_out best = ans_possible[1];
for (int i = 1; i <= n; i++) {
if (i > 1) cout << ", ";
cout << best.stay[i];
}
cout << endl;
cout << "Number of fish expected: " << best.f << endl;
}
return 0;
}