【NOIP2018普及组】摆渡车

在这里插入图片描述
在这里插入图片描述

蒟蒻感言

这道题真的是普及组的难度?!(自闭怀疑人生orz)

分析

动态规划(真的特别玄学,想不出来只能打爆力了)
先对每个人开始等候的时间从小到达排序,并保存当前时间的人数
F[ I][ J ]表示第i个人等了刚好等了J分钟的时刻,前I个人已经到达B地(/上车),所需要的最少总等候时间。
每个人等待的不会超过m ,即 0<=J<m

第k个人的等待时间是:
Tmp=max( t[i] + j + m - t[k], 0 )
f[k][tmp]=f[i][j]+ 第 (i+1)个学生到第 k 个学生的总等车时间(预处理出来)。
最后的状态转移方程如下:

f[k][tmp]=f[i][j]+(tmp+t[k])×(k-i)?(t[k]-t[i])

代码如下

#include<bits/stdc++.h>
using namespace std;
int t[501],s[501],f[501][101];
int read(){
	int sum=0,f=1;
	char ch=getchar();
	while(ch>'9'||ch<'0'){
		if(ch=='-')f=-1;
		ch=getchar();
	}
	while(ch>='0'&&ch<='9'){
		sum=(sum<<3)+(sum<<1)+ch-'0';
		ch=getchar(); 
	}
	return sum*f;
}
const int inf=2139062143;
int main()
{
    int n=read(),m=read();
    for(int i=1;i<=n;i++)
        t[i]=read();
    sort(t+1,t+n+1);
    for(int i=1;i<=n;i++)
        s[i]=s[i-1]+t[i];
    memset(f,0x7f,sizeof(f));
    t[0]=-inf;
    f[0][0]=0;
    for(int i=0;i<=n;i++)
    {
        int MAX=min(m-1,t[i+1]-t[i]);
        for(int j=0;j<=MAX;j++)
            if(f[i][j]!=inf)
                for(int k=1;i+k<=n;k++)
                {
                    int tmp=max(t[i]+j+m-t[i+k],0);
                    f[i+k][tmp]=min(f[i+k][tmp],f[i][j]+(tmp+t[i+k])*k-(s[i+k]-s[i]));
                }
    }
    int ans=inf;
    for(int i=0;i<m;i++)
        ans=min(ans,f[n][i]);
    printf("%d\n",ans);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值