摆渡车(线性dp)

题目描述

n 名同学要乘坐摆渡车从人大附中前往人民大学,第 i位同学在第 ti 分钟去 等车。只有一辆摆渡车在工作,但摆渡车容量可以视为无限大。摆渡车从人大附中出发、 把车上的同学送到人民大学、再回到人大附中(去接其他同学),这样往返一趟总共花费m分钟(同学上下车时间忽略不计)。摆渡车要将所有同学都送到人民大学。

凯凯很好奇,如果他能任意安排摆渡车出发的时间,那么这些同学的等车时间之和最小为多少呢?

注意:摆渡车回到人大附中后可以即刻出发。

输入格式

第一行包含两个正整数 n,m,以一个空格分开,分别代表等车人数和摆渡车往返 一趟的时间。
第二行包含 n 个正整数,相邻两数之间以一个空格分隔,第 i 个非负整数 ti 代 表第 i 个同学到达车站的时刻。

输出格式

输出一行,一个整数,表示所有同学等车时间之和的最小值(单位:分钟)。

输入输出样例

输入
5 1 
3 4 4 3 5 
输出 
0
输入
5 5 
11 13 1 5 5 
输出 
4
 

思路:
dp【i】【j】表示搭载过前i个人,且还有j分钟车才能回来
预处理出每个区间的等待时间,人数作为阶段,还有几分钟回来作为状态,决策就是找到前面的某个状态能使当前等待时间最小的
复杂度O(mn^2)

 
#include
#define ll long long
using namespace std;
ll n,m,dp[510][510],w[510],cost[510][510],ans;
int main()
{
    scanf("%lld%lld",&n,&m);
    for(int i = 1;i<=n;i++)
        scanf("%lld",&w[i]);    
    sort(w+1,w+1+n);
    for(int i = 1;i)
        for(int j = i+1;j<=n;j++)
            cost[i][j] = cost[i][j-1]+(w[j]-w[j-1])*(j-i);
    memset(dp,0x3f,sizeof(dp));
    dp[0][0] = 0;
    for(int i = 1;i<=n;i++)
        for(int j = 0;j)
            for(int k = 0;k<=2*m;k++)
                dp[i][max(m,k-(w[i]-w[j])+m)] = min(dp[i][max(m,k-(w[i]-w[j])+m)],dp[j][k]+cost[j+1][i]+max((ll)0,(k-(w[i]-w[j]))*(i-j)));    
    ans = 0x3f3f3f3f3f3f;
    for(int i = 0;i<=m*2;i++)
        ans = min(ans,dp[n][i]);
    printf("%d",ans);
    return 0;
} 

 

 

你可能感兴趣的:(摆渡车(线性dp))