hoj3440
思想是将位于起始点和结束点之间的所有房子之间的空隙进行扩展。将房子按高度排序,记录排序后每个房子的起始位置。用span[i]记录第i次跳跃的长度。我枚举起始点和结束点之间的每一个空隙,看跳跃过程中所有需要经过这个空隙的所有跳跃中跨度最大的是多少,记录在maxdist中,则经过思考发现,刚才所有跨越此空隙可增加d-maxdist,增加后需要更新span数组。把所有空隙用上述方法扩大后得到答案。
View Code
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
#define maxn 1005
struct House
{
int h, p;
}house[maxn], sorted[maxn];
int n, d, span[maxn], ans;
bool can = false;
bool operator < (const House &a, const House &b)
{
return a.h < b.h;
}
void input()
{
scanf("%d%d", &n ,&d);
for (int i = 0; i < n; i++)
{
scanf("%d", &house[i].h);
house[i].p = i;
sorted[i] = house[i];
}
}
void makespan()
{
ans = abs(sorted[n - 1].p - sorted[0].p);
can = true;
for (int i = 0; i < n - 1; i++)
{
span[i] = abs(sorted[i + 1].p - sorted[i].p);
if (span[i] > d)
can = false;
}
}
void work()
{
int start = min(sorted[0].p, sorted[n - 1].p);
int finish = max(sorted[0].p, sorted[n - 1].p);
for (int i = start; i < finish; i++)
{
int maxdist = 0;
for (int j = 0; j < n - 1; j++)
if ((sorted[j].p <= i && sorted[j + 1].p > i) ||(sorted[j].p > i && sorted[j + 1].p <= i))
maxdist = max(maxdist, span[j]);
for (int j = 0; j < n - 1; j++)
if ((sorted[j].p <= i && sorted[j + 1].p > i) ||(sorted[j].p > i && sorted[j + 1].p <= i))
span[j] += d - maxdist;
ans += d - maxdist;
}
}
int main()
{
//freopen("D:\\t.txt", "r", stdin);
int t;
scanf("%d", &t);
for (int i = 0; i < t; i++)
{
printf("Case %d: ", i + 1);
input();
sort(sorted, sorted + n);
makespan();
if (!can)
{
printf("-1\n");
continue;
}
work();
printf("%d\n", ans);
}
return 0;
}