Problem Statement
Suppose there is a circle. There are N petrol pumps on that circle. Petrol pumps are numbered 0 to (N−1) (both inclusive). You have two pieces of information corresponding to each of the petrol pump: (1) the amount of petrol that particular petrol pump will give, and (2) the distance from that petrol pump to the next petrol pump.
Initially, you have a tank of infinite capacity carrying no petrol. You can start the tour at any of the petrol pumps. Calculate the first point from where the truck will be able to complete the circle. Consider that the truck will stop at each of the petrol pumps. The truck will move one kilometer for each litre of the petrol.
Input Format
The first line will contain the value of
N
.
The next
N
lines will contain a pair of integers each, i.e. the amount of petrol that petrol pump will give and the distnace between that petrol pump and the next petrol pump.
Constraints:
1≤N≤105
1≤amount of petrol, distance≤109
Output Format
An integer which will be the smallest index of the petrol pump from which we can start the tour.
Sample Input
3
1 5
10 3
3 4
Sample Output
1
Explanation
We can start the tour from the second petrol pump.
利用优先队列优化计算dp[i],复杂度O(NlongN)
#include <cmath>
#include <cstdio>
#include <vector>
#include <queue>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 100010;
typedef long long ll;
struct Node {
ll s;
int id;
Node() {}
Node(ll t_s, int t_id) : s(t_s), id(t_id) {}
bool operator < (const Node &p) const {
return s > p.s;
}
};
priority_queue<Node> pq;
void init() {
while(!pq.empty()) pq.pop();
}
inline ll max(ll a, ll b) {
return a > b ? a : b;
}
inline ll min(ll a, ll b) {
return a < b ? a : b;
}
int arr[maxn];
ll pre[maxn], minv[maxn];
ll dp[maxn];
int main() {
Node now;
int ans = -1;
int n, a, b;
scanf("%d", &n);
pre[0] = 0; minv[0] = 0;
init();
for(int i = 1; i <= n; ++i) {
scanf("%d %d", &a, &b);
arr[i] = a - b;
pre[i] = pre[i-1] + arr[i];
pq.push(Node(pre[i], i));
if(i == 1) {
minv[i] = pre[i];
} else {
minv[i] = min(minv[i-1], pre[i]);
}
}
now = pq.top();
for(int i = 1; i <= n; ++i) {
while(now.id < i) {
pq.pop();
now = pq.top();
}
dp[i] = now.s - pre[i-1];
}
for(int i = 1; i <= n; ++i) {
if(dp[i] >= 0) {
ll t = pre[n] - pre[i-1];
if(t + minv[i-1] >= 0) {
ans = i;
break;
}
}
}
printf("%d\n", ans - 1);
return 0;
}
#include <ctime>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <vector>
#include <deque>
#include <list>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <utility>
#include <numeric>
#include <algorithm>
#include <functional>
using namespace std;
const int maxn = 100010;
int a[maxn], b[maxn];
int mld[maxn], mrd[maxn];
int suma[maxn], sumb[maxn];
int main() {
//freopen("aa.in", "r", stdin);
int T, n;
int kcase = 0;
scanf("%d", &T);
while(T--) {
kcase++;
scanf("%d", &n);
for(int i = 1; i <= n; ++i) {
scanf("%d", &a[i]);
}
for(int i = 1; i <= n; ++i) {
scanf("%d", &b[i]);
}
mld[1] = a[1];
suma[1] = a[1];
sumb[1] = 0;
for(int i = 2; i <= n; ++i) {
mld[i] = min(mld[i-1], suma[i-1] - sumb[i-1] - b[i-1]);
suma[i] = suma[i-1] + a[i];
sumb[i] = sumb[i-1] + b[i-1];
}
mrd[n] = a[n];
suma[n] = a[n];
sumb[n] = 0;
for(int i = n - 1; i >= 1; --i) {
mrd[i] = min(a[i] - b[i], mrd[i+1] + (a[i] - b[i]));
suma[i] = suma[i+1] + a[i];
sumb[i] = sumb[i+1] + b[i];
}
int ans = -1;
for(int i = 1; i <= n; ++i) {
int lf = mrd[i];
if(lf < 0) continue;
lf = suma[i] - sumb[i] - b[n];
if(lf < 0) continue;
if(mld[i] + lf >= 0) {
ans = i;
break;
}
}
if(ans < 0) {
printf("Case %d: Not possible\n", kcase);
} else {
printf("Case %d: Possible from station %d\n", kcase, ans);
}
}
return 0;
}