POJ 2609 Ferry Loading 双塔DP

题意:求两个长度为l的车库最多能容纳的车子,如果有一辆车方不进去就停止。

做法:双塔DP啊,只是这次选择的状态是两座塔的高度,用来记录的是最终塔的高度,和放进去车的数量

DFS那里不知怎么的,去掉一个条件就A了,求大神讲解啊

#include<cstdio>
#include<cstring>
const int LMT=10007;
bool dp[2][LMT];
int car[502],sum[502];
int pre[502][LMT];
inline int min(int a,int b)
{
	return a<b?a:b;
}
inline int max(int a,int b)
{
	return a>b?a:b;
}
void dfs(int x,int y)
{
	if(x<=0)return;//我了个去啊。。加个||Y〈=0就错,求各路大神指点
	if(!pre[x][y])
	{
		dfs(x-1,y-car[x]);
		printf("starboard\n");
	}
	else
	{
		dfs(x-1,y);
		printf("port\n");
	}
}
int main(void)
{
	int len,i,j,d,h,cnt=0,ans=0;
	scanf("%d",&len);
	len*=100;
	memset(dp,0,sizeof(dp));
	memset(pre,-1,sizeof(pre));
	dp[0][0]=1;sum[0]=0;
	for(i=1;;i++)
	{
		scanf("%d",&car[i]);
		if(0==car[i])break;
		sum[i]=sum[i-1]+car[i];
		cnt++;
	}
	for(i=1;i<=cnt;i++)
	{
		memset(dp[i&1],0,sizeof(dp[i&1]));
		for(j=len;j>=0;j--)
		{
			if(sum[i]-j>len)break;
			if(j>=car[i]&&dp[(i-1)&1][j-car[i]])//减少选择可以防止逆推时的错误
			{
				dp[i&1][j]|=dp[(i-1)&1][j-car[i]];
				if(dp[i&1][j])
				pre[i][j]=0;
			}
			else if(sum[i]-j>=car[i])
			{
				dp[i&1][j]|=dp[(i-1)&1][j];
				if(dp[i&1][j])
				pre[i][j]=1;
			}
			if(dp[i&1][j])
			{
				ans=d=i;
				h=j;
			}
		}
		if(ans!=i)break;
	}
	printf("%d\n",ans);
	if(ans)
	dfs(d,h);
	return 0;
}


 

你可能感兴趣的:(POJ 2609 Ferry Loading 双塔DP)