Postal Delivery

 

The postal service is interested in cutting costs as an alternative to raising the postage rates. One way to do this is by minimizing the distance traveled when delivering mail from the post office to all the required locations and returning to the post office. It may be that all the mail to be delivered does not fit on the mail truck at once, in which case the distance traveled by the truck must include travel back to the post office to reload. For simplicity, we assume a one dimensional world with the post office at the origin, and delivery locations each identified by a single coordinate. As an example, suppose a postal truck can carry up to 100100100 letters and that 505050 letters need to be delivered to location −10-10−10, that 175175175 need to be delivered to location 101010, and 202020 delivered to location 252525. A maximally efficient plan would be:

Deliver the 505050 letters to location −10-10−10 (travel 2×102 \times 102×10), the first 100100100 letters to location 101010 (travel 2×102 \times 102×10), the remaining 757575 letters to location 101010 while on the way to delivering the 202020 to location 252525 (travel 2×252 \times 252×25). The total round-trip distance traveled is 909090.

Input

The first line contains two integers, NNN and KKK, where 3≤N≤10003 \le N \le 10003≤N≤1000 is the number of delivery addresses on the route, and 1≤K≤100001 \le K \le 100001≤K≤10000 is the carrying capacity of the postal truck. Each of the following NNN lines will contain two integers xjx_jxj​ and tjt_jtj​,the location of a delivery and the number of letters to deliver there, where −1500≤x1<x2<⋯<xN≤1500-1500 \le x_1 < x_2 < \cdots < x_N \le 1500−1500≤x1​<x2​<⋯<xN​≤1500 and 1≤tj≤8001 \le t_j \le 8001≤tj​≤800 for all jjj. All delivery locations are nonzero (that is, none are at the post office).

Output

Output the minimum total travel distance needed to deliver all the letters and return to the post office.

样例输入1

3 100 
-10 50 
10 175
25 20

样例输出1

90

样例输入2

5 3
-1002 800 
-1001 800
-1000 800 
-999 800 
-998 800

样例输出2

2668000

 

题意:有n个需要送信的点,每次可以送m封信,接下来n组,x(地点坐标),y(该地点需要送的信的数量),需要回到原点,问最短走的路程是多少。

思路:按照地点先排好序,计算出坐标轴右侧的,原则是先送最远的,顺带往坐标轴中间凑,能够顺带送的每次都更新。具体看代码。

 

#include<cstdio>
#include<cstring>
#include<queue>
#include<vector>
#include<algorithm>
#include<map>
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
const int mod=1e9+10;
const int M= 1e4 + 10;
struct A
{
    int p,q;
}a[M];
bool cmp(A pp,A qq)
{
    if(pp.p == qq.p)
        return pp.q<qq.q;
    return pp.p<qq.p;
}
int main()
{
    int n,m,i,j,sum=0;
    cin>>n>>m;
    for(i=0;i<n;i++)
    {
        cin>>a[i].p>>a[i].q;
        if(a[i].p >= 0)
            sum++;
    }
    sort(a,a+n,cmp);
    ll ans=0,x,y;
    for(i=n-1;i>= n-sum;i--)//计算坐标轴右侧的
    {
        x=a[i].q/m;
        y=a[i].q%m;
        ans+=x*a[i].p*2;
        if(y!=0)
        {
            ans+=a[i].p*2;//多出来的也按照路程长的来计算
            y=m-y;
            for(j=i-1;j>=n-sum;j--)//更新前面可以顺便送的
            {
                if(a[j].q>=y)
                {
                    a[j].q-=y;
                    y=0;
                    break;
                }
                else//继续向前更新
                {
                    y-=a[j].q;
                    a[j].q=0;
                }
            }
        }
    }
    for(i=0;i<= n-sum-1;i++)//计算坐标轴左侧的
    {
        x=a[i].q/m;
        y=a[i].q%m;
        ans+=x*(-a[i].p)*2;
        if(y!=0)
        {
            ans+=(-a[i].p)*2;
            y=m-y;
            for(j=i+1;j<=n-sum-1;j++)
            {
                if(a[j].q>=y)
                {
                    a[j].q-=y;
                    y=0;
                    break;
                }
                else
                {
                    y-=a[j].q;
                    a[j].q=0;
                }
            }
        }
    }
    cout<<ans<<endl;
    return 0;
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值