前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >POJ 2609 Ferry Loading(双塔DP)

POJ 2609 Ferry Loading(双塔DP)

作者头像
ShenduCC
发布2018-04-26 17:24:19
7350
发布2018-04-26 17:24:19
举报
文章被收录于专栏:算法修养算法修养

Ferry Loading

Time Limit: 1000MS

Memory Limit: 65536K

Total Submissions: 1807

Accepted: 509

Special Judge

Description

Before bridges were common, ferries were used to transport cars across rivers. River ferries, unlike their larger cousins, run on a guide line and are powered by the river's current. Two lanes of cars drive onto the ferry from one end, the ferry crosses the river, and the cars exit from the other end of the ferry.  The cars waiting to board the ferry form a single queue, and the operator directs each car in turn to drive onto the port (left) or starboard (right) lane of the ferry so as to balance the load. Each car in the queue has a different length, which the operator estimates by inspecting the queue. Based on this inspection, the operator decides which side of the ferry each car should board, and boards as many cars as possible from the queue, subject to the length limit of the ferry. Your job is to write a program that will tell the operator which car to load on which side so as to maximize the number of cars loaded. 

Input

The first line of input contains a single integer between 1 and 100: the length of the ferry (in metres). For each car in the queue there is an additional line of input specifying the length of the car (in cm, an integer between 100 and 3000 inclusive). A final line of input contains the integer 0. The cars must be loaded in order, subject to the constraint that the total length of cars on either side does not exceed the length of the ferry. Subject to this constraint as many cars should be loaded as possible, starting with the first car in the queue and loading cars in order until no more can be loaded.

Output

The first line of outuput should give the number of cars that can be loaded onto the ferry. For each car that can be loaded onto the ferry, in the order the cars appear in the input, output a line containing "port" if the car is to be directed to the port side and "starboard" if the car is to be directed to the starboard side. If several arrangements of the cars meet the criteria above, any one will do.

Sample Input

代码语言:javascript
复制
50
2500
3000
1000
1000
1500
700
800
0

Sample Output

代码语言:javascript
复制
6
port
starboard
starboard
starboard
port
port双塔DPn个车要么放左边,要么放右边,最大长度不能超过船的长度这道题目也要记录路径,而且两边的差值有10000,所以必须要用滚动数组了,要不然内存超限。dp[i][j] 第i辆车,两边的差距为j<pre name="code" class="html">#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <algorithm>
#include <stdio.h>
#include <math.h>

using namespace std;
int dp[2][20005];
int d[505];
int e[505];
int a[505];
int ans[505][20005];

int m;
int n;
void dfs(int i,int k)
{
	if(i<=0)
		return;

	if(ans[i][k]<0)
	{
		dfs(i-1,abs(ans[i][k])-2);
		cout<<"port"<<endl;
	}
	else
	{
		dfs(i-1,ans[i][k]);
		cout<<"starboard"<<endl;
	}
}
int main()
{
	scanf("%d",&m);

	m*=100;
	int x;
	scanf("%d",&x);
	int n=0;
	while(x!=0)
	{
		a[++n]=x;
		scanf("%d",&x);
	}
	memset(dp,-1,sizeof(dp));
	memset(ans,-1,sizeof(ans));
	dp[0][0+10000]=0;
	int now=1;
	for(int i=1;i<=n;i++)
		d[i]=10000000;
	for(int i=1;i<=n;i++)
	{
		for(int j=-10000;j<=10000;j++)
		{
			if(dp[now^1][j+10000]>m) continue;
			if(dp[now^1][j+10000]==-1)
				continue;

			if(j<0)
			{
				if(j+10000-a[i]>=0)//不写会re
				{
					dp[now][j+10000-a[i]]=dp[now^1][j+10000]+a[i];
					if(d[i]>dp[now][j+10000-a[i]])
					{
						d[i]=dp[now][j+10000-a[i]];//记录第i辆车形成的最小长度
						e[i]=j+10000-a[i];//第i辆车形成最小长度的差值,
					}

					ans[i][j+10000-a[i]]=(j+10000)*(-1)-2;//记录路径
				}
				dp[now][j+10000+a[i]]=dp[now^1][j+10000]+max(0,j+a[i]);
				if(d[i]>dp[now][j+10000+a[i]])
				{

					d[i]=dp[now][j+10000+a[i]];
					e[i]=j+10000+a[i];
				}


				ans[i][j+10000+a[i]]=j+10000; 
			}
			else
			{
				if(j+10000+a[i]<=20000)
				{
					dp[now][j+10000+a[i]]=dp[now^1][j+10000]+a[i];
					if(d[i]>dp[now][j+10000+a[i]])
					{

						d[i]=dp[now][j+10000+a[i]] ;
						e[i]=j+10000+a[i];
					}
					ans[i][ j+10000+a[i]]=j+10000;
				}

				dp[now][j+10000-a[i]]=dp[now^1][j+10000]+max(0,a[i]-j);
				if(d[i]>dp[now][j+10000-a[i]])
				{
					d[i]=dp[now][j+10000-a[i]];
					e[i]= j+10000-a[i];
				}
				ans[i][j+10000-a[i]]=(j+10000)*(-1)-2; 
			}
		}
		memset(dp[now^1],-1,sizeof(dp[now^1]));
		now^=1;
		if(d[i]>m)
			break;
	}
	int i;
	for(i=n;i>=1;i--)
	{
		if(d[i]<=m)
			break;
	}
	printf("%d\n",i);
	dfs(i,e[i]);



	return 0;
}
代码语言:javascript
复制
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2016-05-07 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档