关闭

POJ 2336 Ferry Loading II [贪心 DP]

858人阅读 评论(0) 收藏 举报

题意:

摆渡:每次可以摆渡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
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:301302次
    • 积分:5089
    • 等级:
    • 排名:第5675名
    • 原创:225篇
    • 转载:13篇
    • 译文:1篇
    • 评论:26条
    最新评论