摆渡车(线性dp)
Posted loganacmer
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了摆渡车(线性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<bits/stdc++.h> #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<n;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<i;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)的主要内容,如果未能解决你的问题,请参考以下文章