8VC Venture Cup 2016 - Final Round (Div2) E
贪心。当前位置满油可达的gas station中,如果有比它小的,则加油至第一个比他小的。没有,则加满油,先到达这些station中最小的。注意数的范围即可。
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #define LL long long using namespace std; const int MAXN = 200050; int d, n, m; int gp[MAXN], gpz[MAXN]; int fl[MAXN]; struct gas{ int pos, price; }g[MAXN]; bool cmp(gas a, gas b){ if(a.pos < b.pos) return true; return false; } int main(){ scanf("%d%d%d", &d, &n, &m); gp[0] = 0, gpz[0] = 1e7; for(int i = 1; i <= m; i++){ scanf("%d%d", &g[i].pos, &g[i].price); } sort(g + 1, g + 1 + m, cmp); for(int i = 1; i <= m; i++){ gp[i] = g[i].pos, gpz[i] = g[i].price; } gp[m + 1] = d, gpz[m + 1] = 0; /* for(int i = 0; i<= m + 1; i++) cout <<gp[i] <<" "<< gpz[i] << endl; cout << endl; */ int mindist = -1; for(int i = 0; i <= m; i++){ mindist = max(mindist, gp[i + 1] - gp[i]); } // cout << mindist << endl; if(mindist > n){ puts("-1"); return 0; } if(d <= n){ puts("0"); return 0; } for(int i = m; i >= 0; i--){ if(gpz[i + 1] <= gpz[i]){ fl[i] = i + 1; } else { int tmp = i + 1; while(gpz[fl[tmp]] > gpz[i]){ tmp = fl[tmp]; } fl[i] = fl[tmp]; } } /* for(int i = 0; i<= m; i++){ cout << fl[i] <<" "; } cout << endl; */ LL ans = 0; int liter = n; for(int l = 0; l < m+ 1; ){ if(gp[fl[l]] - gp[l] > n){ ans += (LL)(n - liter) * gpz[l]; int tmp = l + 1; while(gp[fl[tmp]] - gp[l] <= n){ tmp = fl[tmp]; } liter = n - (gp[tmp] - gp[l]); l = tmp; } else{ int tmp = fl[l]; if(tmp == m + 1){ ans += (LL)(d - gp[l] - liter) * gpz[l]; break; } else{ if(gp[tmp] - gp[l] <= liter){ liter -= gp[tmp] - gp[l]; } else{ ans += (LL)(gp[tmp] - gp[l] - liter)*gpz[l]; liter = 0; } l = tmp; } } // cout << l << endl; // system("pause"); } cout << ans << endl; }