题意:求两个长度为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;
}