Pagini recente » Cod sursa (job #1433450) | Cod sursa (job #2452602) | Cod sursa (job #2713778) | Cod sursa (job #2327603) | Cod sursa (job #945665)
Cod sursa(job #945665)
//O(N lg N)
//pe scurt: cand zombieul <i> intra pe strada, am 2 optiuni:
// 1 - folosesc dp[i-1] pentru zombii de dinainte, si 1 pentru zombieul curent, omorat singur. dp[i] = dp[i-1] + 1;
// 2 - folosesc vraja 2, si omor zombieul curent alaturi de toti zombii anteriori care se afla inca pe strada
// dp[i] = dp[j] + k
// unde j = cel mai recent zombie care nu se mai afla pe strada (o fost omorat deci anterior), asa ca ma folosesc de dp[j]
// si k = costul vrajii 2, cu care omor toti zombii aflati in prezent pe strada (j+1 -> i)
//la fiecare pas, aleg minimul dintre cele 2
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#define nmax 1000005
#define inf 1<<30
using namespace std;
int d, n, k, lo, hi, mid;
int dp[nmax], v[nmax];
int main() {
ifstream f("zombie.in");
ofstream g("zombie.out");
f>>d>>n>>k;
dp[0] = 0;
for(int i=1; i<=n; i++) {
f>>v[i];
dp[i] = dp[i-1] + 1; //pp. ca omor zombie-ul actual, singur
//trebuie sa gasesc cel mai din stanga zombie care inca se afla pe strada
//adica v[i] - v[j] <= d
//<==> v[j] >= v[i]-d, v[j] = minim
lo = 0;
hi = i;
while(hi - lo > 1) {
mid = lo + (hi-lo) / 2;
if(v[mid] < v[i]-d) lo = mid;
else hi = mid;
}
//acum hi = cel mai din stanga zombie care se afla pe strada
hi--;
dp[i] = min(dp[i], dp[hi] + k);
}
g<<dp[n]<<"\n";
return 0;
}