河南省多校联萌(四)

点击打开链接

Problem J: GJJ的日常之购物

Time Limit: 3 Sec   Memory Limit: 128 MB
Submit: 9   Solved: 8

Submit Web Board

Description

一天,GJJ去购物,来到商场门口,GJJ计划要买n个商品,第i个商品的坐标为(xi,yi),重量是wi。
GJJ比较任性,想按照商品编号从小到大的顺序将所有的商品的搬到车里(车在(0,0)的位置);
GJJ可以几个商品一起搬,但在任何时候GJJ手中的商品重量不能超过最大载重C。
商场的过道只有横着的和竖着的。求GJJ行走的最短距离(GJJ的起始位置为(0,0))。

Input

第一行输入一个T(T<=10),表示T组数据。
每组数据第一行为最大载重C(1<=C<=100),商品个数n(n<=100000);
接下来n行,每行为xi,yi,wi,(0<=xi,yi<=100,wi<=C)既商品的坐标和重量

Output

对于每组数据,输出总路径的最短长度。

Sample Input

2
10 4
1 2 3
1 0 3
3 1 4
3 1 4
5 1
1 1 2

Sample Output

14
4

HINT


1
#include<bits/stdc++.h>
2
using namespace std;
3
int x[100010],y[100010],z[100010];
4
int d[100010],dd[100010];
5
int dp[100010];
6
struct Q
7
{
8
    int x,id;
9
    bool operator < (const Q &r)const
10
    {
11
        return  x>r.x;
12
    }
13
};
14
int main()
15
{
16
    int t;
17
//    freopen("D://1.in","r",stdin);
18
//    freopen("D://1.out","w",stdout);
19
    scanf("%d",&t);
20
    while(t--)
21
    {
22
        int c,n;
23
        scanf("%d%d",&c,&n);
24
        for(int i=1; i<=n; i++)
25
        {
26
            scanf("%d%d%d",&x[i],&y[i],&z[i]);
27
            d[i]=abs(x[i])+abs(y[i]);
28
            dd[i]=dd[i-1]+abs(x[i]-x[i-1])+abs(y[i]-y[i-1]);
29
        }
30
        int l=0,w=0;
31
        priority_queue<Q>p;
32
        p.push((Q)
33
        {
34
            0,0
35
        });
36
        for(int i=1; i<=n; i++)
37
        {
38
            w+=z[i];
39
            while(w>c)w-=z[l++];
40
            while(p.top().id+1<l)
41
            {
42
                p.pop();
43
            }
44
            dp[i]=p.top().x+d[i]+dd[i];
45
            p.push((Q)
46
            {
47
                dp[i]-dd[i+1]+d[i+1],i
48
            });
49
        }
50
        printf("%d\n",dp[n]);
51
52
    }
53
    return 0;
54
}



我们设d[i]为从原点出发,将前i个商品放到车中的最小距离,则:
d[i]=min(d[j]+dist2[j+1]+dist[i]-dist[j+1]+dist2[i])
   =min(d[j]-dist[j+1]+dist2[j+1])+dist[i]+dist2[i]      (j<i;j+1到i的重量和<=C.)

dist[i]表示从原点出发,依次经过1,2,3。。到i所走的距离
dist2[i]表示从原点直接到i商品的距离,既abs(xi)+abs(yi);


min(d[j]-dist[j+1]+dist2[j+1])要满足j<i;j+1到i的重量和<=C.可以用一个滑动窗口去维护,
最简单的就是优先队列维护,复杂度O(T*n*logn)








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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值