POJ 2336 Ferry Loading II [贪心 DP]

题意:

摆渡:每次可以摆渡n辆车,摆渡要来回的,去和返的时间一样都是t,有m辆车需要摆渡。

这m辆车抵达码头的时间给定。

问如果摆渡,可以使摆渡完所有的车的时间最少。

且输出这个条件下,最少的来回数。


思路:

贪心+dp。

现在要满足总时间最少,则最晚抵达的车要尽早摆渡过岸。

假设最晚抵达的车,车号为m的时间为 40。

则最后一趟摆渡出发的时间可以是t>=40的区间都可以.但是当然 t 越小越好。


先进行一下贪心:

因为每次摆渡可以运n辆车,则最后一车的时候还可以一起顺带n-1辆车。

怎么选这n-1辆车呢?显然是m-1,m-2...m-n+1一起。

因为越后面的车辆,摆渡的时间容许度越苛刻。如果


m-2,10.

m-1,30.

m,40.

对于m-2可以在>=10的时间内摆渡,m-1可以在>=30的时间内摆渡。

m-1的摆渡时间 真包含于 m-2的摆渡时间。

所以将m-1顺带带走显然比带走m-2的车更佳,起码不会更坏。


然后是dp的转移方程:

dp[i]=Max(dp[i-n]+2*t,a[i]);

注意就是这里dp[i]的i是从m开始,i=m,i=m-n,i=m-2*n....按每n个车作为一个集合来处理的。

最后一个集合有可能不足n辆车。

因为m%n不一定等于0.


先写的上面这些思路,再写的下面的代码。

一次AC,没啥陷阱。


#include<iostream>
#include<vector>
#include<string>
#include<queue>
#include<cmath>
#include<algorithm>
#define llong long long
#define Min(a,b) (a<b?a:b)
#define Max(a,b) (a>b?a:b)
#define Abs(a) ((a)>0?(a):-(a))
#define Mod(a,b) (((a)-1+(b))%(b)+1)
using namespace std;
int n,m,t;
const int N=1505;
const int M=105;
const int inf=2099999999;
int a[N];
int dp[N];
int main()
{
	int T;
	scanf("%d",&T);
	while(T--)
	{
		memset(dp,0,sizeof(dp));
		scanf("%d%d%d",&n,&t,&m);
		for(int i=1;i<=m;i++)
			scanf("%d",a+i);
		int now=m%n,count=1;
		if(!now)
		{
			now=n;
		}
		dp[now]=a[now];
		now+=n;
		while(now<=m)
		{
			count++;
			dp[now]=Max(dp[now-n]+2*t,a[now]);
			now+=n;
		}
		printf("%d %d\n",dp[m]+t,count);
	}
	
	return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值