我正在处理一个间隔计划问题,问题描述如下:
说明:Lanran有N个朋友。每个星期天,兰兰都要玩 和他的朋友。第i个朋友可以在时间a至 时间b(包括a和b)。但是,兰兰必须与每个人一起玩 相同时间的朋友兰兰想和 他的朋友越长越好。但是他很愚蠢。所以他要求 您的帮助,以计算他可以和他每个人玩的最长时间 朋友。
输入第一行包含一个整数N。接下来的N个每一个(N <= 5000)行包含两个整数a和b(1 <= a,b <= 10000),其中 显示第i个朋友的时间间隔。
Output输出单个整数,显示Lanran可以播放的最长时间 和他的每个朋友。
我认为这是一个贪婪的问题,因此我选择了最短时间的朋友,即已经播放的时间+直到b的可能的播放时间,然后在第i秒与他一起玩。这是代码:
#include <bits/stdc++.h>
using namespace std;
const int N = 5010;
int n, s[N], e[N], cnt[N], me;
void swap(int *a, int *b) {
int temp = *a;
*a = *b;
*b = temp;
}
int partition(int low, int high) {
int pivot = s[high];
int i = (low - 1);
for (int j = low; j <= high - 1; j++) {
if (s[j] <= pivot) {
i++;
swap(&s[i], &s[j]);
swap(&e[i], &e[j]);
}
}
swap(&s[i + 1], &s[high]);
swap(&e[i + 1], &e[high]);
return (i + 1);
}
void quickSort(int low, int high) {
if (low < high) {
int pi = partition(low, high);
quickSort(low, pi - 1);
quickSort(pi + 1, high);
}
}
int main() {
scanf("%d", &n);
for (int i = 0; i < n; ++i) {
scanf("%d%d", &s[i], &e[i]);
if (e[i] < s[i]) { printf("0\n"); return 0; }
if (e[i] > me) me = e[i];
}
quickSort(0, n - 1);
for (int i = 1; i <= me; ++i) {
int id = -1, mi = 0x7fffffff;
for (int j = 0; j < n; ++j) {
if (s[j] > i || i > e[j]) continue;
if (cnt[j] + e[j] - i + 1 < mi) { id = j; mi = cnt[j] + e[j] - i + 1; }
}
++cnt[id];
}
int ans = 0x7fffffff;
for (int i = 0; i < n; ++i) if (cnt[i] < ans) ans = cnt[i];
printf("%d\n", ans);
return 0;
}
那么我会做错什么吗?我在10个测试用例中得到7个错误答案。
答案 0 :(得分:0)
看起来与标准活动选择问题相同。我正在粘贴相关的标准算法。您可以找到Wiki:https://en.wikipedia.org/wiki/Activity_selection_problem。 贪婪迭代活动选择器(A,s,f):
Sort A by finish times stored in f
S = {A[1]}
k = 1
n = A.length
for i = 2 to n:
if s[i] ≥ f[k]:
S = S U {A[i]}
k = i
return S