题目1 : 自行车架
时间限制:
5000ms
单点时限:
1000ms
内存限制:
256MB
-
4 2 1 2 1 0 0 2 0 2 1 2 2
样例输出
-
7 1 5 7
描述
小Hi的宿舍楼下有一块用于停自行车的区域。平时自行车都停得非常杂乱,于是楼长打算去买一排自行车架用来停车。自行车架一般有P个槽,每个槽的两侧都可以停入自行车;但是一个槽位同时只能有一侧停入自行车。此外,停入一辆自行车会导致无法在这一侧的附近若干个槽位中停入自行车。
经过调查,这栋宿舍楼的学生共拥有N辆A型自行车、M辆B型自行车和K辆C型自行车。其中A型自行车会导致这一侧的左右各1个槽位不能使用,B型自行车会导致这一侧的左右2个槽位不能使用,C型自行车会导致这一侧的左右3个槽位不能使用。
现给定N、M和K,楼长希望知道P至少要是多少,才能将所有自行车都停入。
如图中所示,P最少为7就可以存放下2辆A型,1辆B型和2辆C型。
输入
每个输入文件包含多组测试数据,在每个输入文件的第一行为一个整数Q,表示测试数据的组数。
每组测试数据为3个整数N、M和K,意义如前文所述。
对于20%的数据,满足0<=N、M、K<=2,Q=100
对于40%的数据,满足0<=N、M、K<=50,Q=100
对于100%的数据,满足0<=N、M、K<=50,1<=Q<=100000
输出
对于每组测试数据,输出一个整数P,表示自行车架至少需要的槽位。
代码:
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
int dp[52][52][52][4][4][4];
void algo()
{
int a,b,n=50;
dp[0][0][0][0][0][0]=0;
for (int i=0;i<=n;i++)
{
for (int j=0;j<=n;j++)
{
for (int k=0;k<=n;k++)
{
if (i)
{
for (int ii=0;ii<=3;ii++)
{
for (int jj=0;jj<=3;jj++)
{
for (int kk=0;kk<=3;kk++)
{
if (dp[i-1][j][k][ii][jj][kk]==-1) continue;
if (ii==0)
a=1;
else
a=max(ii+1,2);
if (jj==0)
b=1;
else
b=max(jj+1,2);
b-=kk;
if (b<1) b=1;
if (a<b)
{
if (dp[i][j][k][1][jj][kk+a]==-1)
dp[i][j][k][1][jj][kk+a]=dp[i-1][j][k][ii][jj][kk]+a;
else
dp[i][j][k][1][jj][kk+a]=min(dp[i][j][k][1][jj][kk+a],dp[i-1][j][k][ii][jj][kk]+a);
}
else
{
if (dp[i][j][k][1][ii][b]==-1)
dp[i][j][k][1][ii][b]=dp[i-1][j][k][ii][jj][kk]+b;
else
dp[i][j][k][1][ii][b]=min(dp[i-1][j][k][ii][jj][kk]+b,dp[i][j][k][1][ii][b]);
}
}
}
}
}
if (j)
{
for (int ii=0;ii<=3;ii++)
{
for (int jj=0;jj<=3;jj++)
{
for (int kk=0;kk<=3;kk++)
{
if (dp[i][j-1][k][ii][jj][kk]==-1) continue;
if (ii==0)
a=1;
else
a=max(ii+1,3);
if (jj==0)
b=1;
else
b=max(jj+1,3);
b-=kk;
if (b<1) b=1;
if (a<b)
{
if (dp[i][j][k][2][jj][kk+a]==-1)
dp[i][j][k][2][jj][kk+a]=dp[i][j-1][k][ii][jj][kk]+a;
else
dp[i][j][k][2][jj][kk+a]=min(dp[i][j][k][i][jj][kk+a],dp[i][j-1][k][2][jj][kk]+a);
}
else
{
if (dp[i][j][k][2][ii][b]==-1)
dp[i][j][k][2][ii][b]=dp[i][j-1][k][ii][jj][kk]+b;
else
dp[i][j][k][2][ii][b]=min(dp[i][j-1][k][ii][jj][kk]+b,dp[i][j][k][2][ii][b]);
}
}
}
}
}
if (k)
{
for (int ii=0;ii<=3;ii++)
{
for (int jj=0;jj<=3;jj++)
{
for (int kk=0;kk<=3;kk++)
{
if (dp[i][j][k-1][ii][jj][kk]==-1) continue;
if (ii==0)
a=1;
else
a=max(ii+1,4);
if (jj==0)
b=1;
else
b=max(jj+1,4);
b-=kk;
if (b<1) b=1;
if (a<b)
{
if (dp[i][j][k][3][jj][kk+a]==-1)
dp[i][j][k][3][jj][kk+a]=dp[i][j][k-1][ii][jj][kk]+a;
else
dp[i][j][k][3][jj][kk+a]=min(dp[i][j][k][3][jj][kk+a],dp[i][j][k-1][ii][jj][kk]+a);
}
else
{
if (dp[i][j][k][3][ii][b]==-1)
dp[i][j][k][3][ii][b]=dp[i][j][k-1][ii][jj][kk]+b;
else
dp[i][j][k][3][ii][b]=min(dp[i][j][k-1][ii][jj][kk]+b,dp[i][j][k][3][ii][b]);
}
}
}
}
}
}
}
}
}
int main()
{
memset(dp,-1,sizeof(dp));
algo();
int q,n,m,k,ans;
cin>>q;
while (q--)
{
cin>>n>>m>>k;
ans=99999999;
for (int i=0;i<=3;i++)
{
for (int j=0;j<=3;j++)
{
for (int p=0;p<=3;p++)
{
if (dp[n][m][k][i][j][p]!=-1)
ans=min(ans,dp[n][m][k][i][j][p]);
}
}
}
cout<<ans<<endl;
}
return 0;
}