HDU 3884(水过O(N ^ 2)的复杂度)

题目连接: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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值