题目连接:http://acm.split.hdu.edu.cn/showproblem.php?pid=3884
题目大意:在花费限制为K的情况下,把最多的植物移动到同一个点,每一个植物移动的花费为移动的距离;
一看数据是10^4,如果暴力是n^2,肯定过不了
但是AC了,让我不禁烦死了一小会.......
当我们得知算法的复杂度为n方时,可以再深入分析,第一个n是必须完整遍历的,但是第二个n就是随机了,不一定完整遍历,所以可以试一试,不过真心不建议在比赛中试验这种题目,如果真的TLE,会浪费时间。
AC如下
LL cost = min(cost1 , cost2);
if(k < cost) break;
这个判断必须加,不加的TLE原因是在k不足以完成之后的mov时,跳出循环,避免不必要的查询
#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> P;
typedef long long LL;
#define INF 0x3f3f3f3f
#define PI acos(-1)
#define MAX_N 10005
#define LOCAL
struct node
{
LL x, p;
}A[MAX_N];
bool mycmp(node c, node d)
{
return c.x < d.x;
}
//int cmp(const void *p1,const void *p2) //quickly sort
//{
// return ((struct node *)p1)->x-((struct node *)p2)->x;
//}
int main()
{
#ifdef LOCAL
freopen("b:\\data.in.txt", "r", stdin);
#endif
LL n, K;
while(~scanf("%I64d%I64d", &n, &K))
{
for(int i = 0; i < n; i++)
{
scanf("%I64d%I64d", &A[i].x, &A[i].p);
}
// qsort(A, n, sizeof(A[0]), cmp);
sort(A, A+n, mycmp);
LL ans = -INF;
for(int i = 0; i < n; i++) //枚举每个点
{
LL nowsum = A[i].p;
LL k = K;
LL le, ri;
le = i-1;
ri = i+1;
while(k > 0)
{
if(le < 0)
le = i;
if(ri >= n)
ri = i;
if(ri == i && le == i) break; //到达边界
LL cost1 = INF;
LL cost2 = INF;
if(le != i) cost1 = A[i].x - A[le].x;
if(ri != i) cost2 = A[ri].x - A[i].x;
LL cost = min(cost1 , cost2);
if(k < cost) break;
if(cost1 < cost2) //left is pre
{
nowsum += min(k/cost1, A[le].p);
k -= cost1 * min(k/cost1, A[le].p);
le--;
}
else
if(cost1 == cost2)
{
nowsum += min(k/cost1, A[le].p + A[ri].p);
k -= cost1 * min(k/cost1, A[le].p+ A[ri].p);
le--;
ri++;
}
else
{
nowsum += min(k/cost2, A[ri].p);
k -= cost2 * min(k/cost2, A[ri].p);
ri++;
}
}
if(nowsum > ans) ans = nowsum;
}
printf("%I64d\n", ans);
}
return 0;
}