题意:有个人去一幢楼送礼物,他用两根柱状的容器装礼物,每次只能从容器的两端取出礼物送出去,上一层楼花费5的体力,下一层楼花费3的体力。求送完所有礼物耗费的最少体力。
分析:不难的题目,只是目前写的人比较少而已。状态表示还是很好想出来的。
dp[i1][j1][i2][j2][0]--第一根柱子到两端为i1,j1都送完,第二根到两端为i2,j2都送完,最后送的是a[i1]这个礼物所花费的最小体力。
dp[i1][j1][i2][j2][1]--第一根柱子到两端为i1,j1都送完,第二根到两端为i2,j2都送完,最后送的是a[j1]这个礼物所花费的最小体力。
dp[i1][j1][i2][j2][2]--第一根柱子到两端为i1,j1都送完,第二根到两端为i2,j2都送完,最后送的是b[i2]这个礼物所花费的最小体力。
dp[i1][j1][i2][j2][3]--第一根柱子到两端为i1,j1都送完,第二根到两端为i2,j2都送完,最后送的是b[j2]这个礼物所花费的最小体力。
这样的话,转移就很明显了,每种状态都有可能由4种状态转移过来,具体转移看代码。
如果方程的最后一维表示的是最后停在哪一层的话,就不行了,30*30*30*30*100的空间肯定是开不了的,所以用最后一维表示最后送出的礼物是哪一个,时空复杂度都降低了。
#include <iostream>
#include 
<stdio.h>
#include 
<memory.h>
using namespace std;
#define inf 2000000000

int dp[32][32][32][32][4],n,m,a[32],b[32];

int main()
{
    
int t,i,j,i1,j1,i2,j2,ans,cost,zt;
    scanf(
"%d",&t);
    
while(t--)
    
{
        scanf(
"%d",&n);
        
for(i=1;i<=n;i++) scanf("%d",a+i);
        scanf(
"%d",&m);
        
for(i=1;i<=m;i++) scanf("%d",b+i);

        a[
0]=1; a[n+1]=1; b[0]=1; b[m+1]=1// 这里设置这些虚拟的楼层是为了方便设置边界

        memset(dp,
-1,sizeof(dp));
        dp[
0][n+1][0][m+1][0]=0;      // 初始化
        dp[0][n+1][0][m+1][1]=0;
        dp[
0][n+1][0][m+1][2]=0;
        dp[
0][n+1][0][m+1][3]=0;

        
for(i1=0;i1<=n;i1++)
        
{
            
for(j1=n+1;j1>i1;j1--)
            
{
                
for(i2=0;i2<=m;i2++)
                
{
                    
for(j2=m+1;j2>i2;j2--)     // 下面就是转移过程了
                    {
                        
if(i1>0&&dp[i1-1][j1][i2][j2][0]!=-1)
                        
{
                            
if(a[i1]>a[i1-1]) cost=(a[i1]-a[i1-1])*5;
                            
else cost=(a[i1-1]-a[i1])*3;
                            
if(dp[i1-1][j1][i2][j2][0]+cost<dp[i1][j1][i2][j2][0]||dp[i1][j1][i2][j2][0]==-1)
                                dp[i1][j1][i2][j2][
0]=dp[i1-1][j1][i2][j2][0]+cost;
                        }

                        
if(i1>0&&dp[i1-1][j1][i2][j2][1]!=-1)
                        
{
                            
if(a[i1]>a[j1]) cost=(a[i1]-a[j1])*5;
                            
else cost=(a[j1]-a[i1])*3;
                            
if(dp[i1-1][j1][i2][j2][1]+cost<dp[i1][j1][i2][j2][0]||dp[i1][j1][i2][j2][0]==-1)
                                dp[i1][j1][i2][j2][
0]=dp[i1-1][j1][i2][j2][1]+cost;
                        }

                        
if(i1>0&&dp[i1-1][j1][i2][j2][2]!=-1)
                        
{
                            
if(a[i1]>b[i2]) cost=(a[i1]-b[i2])*5;
                            
else cost=(b[i2]-a[i1])*3;
                            
if(dp[i1-1][j1][i2][j2][2]+cost<dp[i1][j1][i2][j2][0]||dp[i1][j1][i2][j2][0]==-1)
                                dp[i1][j1][i2][j2][
0]=dp[i1-1][j1][i2][j2][2]+cost;
                        }

                        
if(i1>0&&dp[i1-1][j1][i2][j2][3]!=-1)
                        
{
                            
if(a[i1]>b[j2]) cost=(a[i1]-b[j2])*5;
                            
else cost=(b[j2]-a[i1])*3;
                            
if(dp[i1-1][j1][i2][j2][3]+cost<dp[i1][j1][i2][j2][0]||dp[i1][j1][i2][j2][0]==-1)
                                dp[i1][j1][i2][j2][
0]=dp[i1-1][j1][i2][j2][3]+cost;
                        }

/*--------------------------------------------------------------------------------------------------------*/
                        
if(j1<n+1&&dp[i1][j1+1][i2][j2][0]!=-1)
                        
{
                            
if(a[j1]>a[i1]) cost=(a[j1]-a[i1])*5;
                            
else cost=(a[i1]-a[j1])*3;
                            
if(dp[i1][j1+1][i2][j2][0]+cost<dp[i1][j1][i2][j2][1]||dp[i1][j1][i2][j2][1]==-1)
                                dp[i1][j1][i2][j2][
1]=dp[i1][j1+1][i2][j2][0]+cost;
                        }

                        
if(j1<n+1&&dp[i1][j1+1][i2][j2][1]!=-1)
                        
{
                            
if(a[j1]>a[j1+1]) cost=(a[j1]-a[j1+1])*5;
                            
else cost=(a[j1+1]-a[j1])*3;
                            
if(dp[i1][j1+1][i2][j2][1]+cost<dp[i1][j1][i2][j2][1]||dp[i1][j1][i2][j2][1]==-1)
                                dp[i1][j1][i2][j2][
1]=dp[i1][j1+1][i2][j2][1]+cost;
                        }

                        
if(j1<n+1&&dp[i1][j1+1][i2][j2][2]!=-1)
                        
{
                            
if(a[j1]>b[i2]) cost=(a[j1]-b[i2])*5;
                            
else cost=(b[i2]-a[j1])*3;
                            
if(dp[i1][j1+1][i2][j2][2]+cost<dp[i1][j1][i2][j2][1]||dp[i1][j1][i2][j2][1]==-1)
                                dp[i1][j1][i2][j2][
1]=dp[i1][j1+1][i2][j2][2]+cost;
                        }

                        
if(j1<n+1&&dp[i1][j1+1][i2][j2][3]!=-1)
                        
{
                            
if(a[j1]>b[j2]) cost=(a[j1]-b[j2])*5;
                            
else cost=(b[j2]-a[j1])*3;
                            
if(dp[i1][j1+1][i2][j2][3]+cost<dp[i1][j1][i2][j2][1]||dp[i1][j1][i2][j2][1]==-1)
                                dp[i1][j1][i2][j2][
1]=dp[i1][j1+1][i2][j2][3]+cost;
                        }

/*--------------------------------------------------------------------------------------------------------*/
                        
if(i2>0&&dp[i1][j1][i2-1][j2][0]!=-1)
                        
{
                            
if(b[i2]>a[i1]) cost=(b[i2]-a[i1])*5;
                            
else cost=(a[i1]-b[i2])*3;
                            
if(dp[i1][j1][i2-1][j2][0]+cost<dp[i1][j1][i2][j2][2]||dp[i1][j1][i2][j2][2]==-1)
                                dp[i1][j1][i2][j2][
2]=dp[i1][j1][i2-1][j2][0]+cost;
                        }

                        
if(i2>0&&dp[i1][j1][i2-1][j2][1]!=-1)
                        
{
                            
if(b[i2]>a[j1]) cost=(b[i2]-a[j1])*5;
                            
else cost=(a[j1]-b[i2])*3;
                            
if(dp[i1][j1][i2-1][j2][1]+cost<dp[i1][j1][i2][j2][2]||dp[i1][j1][i2][j2][2]==-1)
                                dp[i1][j1][i2][j2][
2]=dp[i1][j1][i2-1][j2][1]+cost;
                        }

                        
if(i2>0&&dp[i1][j1][i2-1][j2][2]!=-1)
                        
{
                            
if(b[i2]>b[i2-1]) cost=(b[i2]-b[i2-1])*5;
                            
else cost=(b[i2-1]-b[i2])*3;
                            
if(dp[i1][j1][i2-1][j2][2]+cost<dp[i1][j1][i2][j2][2]||dp[i1][j1][i2][j2][2]==-1)
                                dp[i1][j1][i2][j2][
2]=dp[i1][j1][i2-1][j2][2]+cost;
                        }

                        
if(i2>0&&dp[i1][j1][i2-1][j2][3]!=-1)
                        
{
                            
if(b[i2]>b[j2]) cost=(b[i2]-b[j2])*5;
                            
else cost=(b[j2]-b[i2])*3;
                            
if(dp[i1][j1][i2-1][j2][3]+cost<dp[i1][j1][i2][j2][2]||dp[i1][j1][i2][j2][2]==-1)
                                dp[i1][j1][i2][j2][
2]=dp[i1][j1][i2-1][j2][3]+cost;
                        }

/*--------------------------------------------------------------------------------------------------------*/
                        
if(j2<m+1&&dp[i1][j1][i2][j2+1][0]!=-1)
                        
{
                            
if(b[j2]>a[i1]) cost=(b[j2]-a[i1])*5;
                            
else cost=(a[i1]-b[j2])*3;
                            
if(dp[i1][j1][i2][j2+1][0]+cost<dp[i1][j1][i2][j2][3]||dp[i1][j1][i2][j2][3]==-1)
                                dp[i1][j1][i2][j2][
3]=dp[i1][j1][i2][j2+1][0]+cost;
                        }

                        
if(j2<m+1&&dp[i1][j1][i2][j2+1][1]!=-1)
                        
{
                            
if(b[j2]>a[j1]) cost=(b[j2]-a[j1])*5;
                            
else cost=(a[j1]-b[j2])*3;
                            
if(dp[i1][j1][i2][j2+1][1]+cost<dp[i1][j1][i2][j2][3]||dp[i1][j1][i2][j2][3]==-1)
                                dp[i1][j1][i2][j2][
3]=dp[i1][j1][i2][j2+1][1]+cost;
                        }

                        
if(j2<m+1&&dp[i1][j1][i2][j2+1][2]!=-1)
                        
{
                            
if(b[j2]>b[i2]) cost=(b[j2]-b[i2])*5;
                            
else cost=(b[i2]-b[j2])*3;
                            
if(dp[i1][j1][i2][j2+1][2]+cost<dp[i1][j1][i2][j2][3]||dp[i1][j1][i2][j2][3]==-1)
                                dp[i1][j1][i2][j2][
3]=dp[i1][j1][i2][j2+1][2]+cost;
                        }

                        
if(j2<m+1&&dp[i1][j1][i2][j2+1][3]!=-1)
                        
{
                            
if(b[j2]>b[j2+1]) cost=(b[j2]-b[j2+1])*5;
                            
else cost=(b[j2+1]-b[j2])*3;
                            
if(dp[i1][j1][i2][j2+1][3]+cost<dp[i1][j1][i2][j2][3]||dp[i1][j1][i2][j2][3]==-1)
                                dp[i1][j1][i2][j2][
3]=dp[i1][j1][i2][j2+1][3]+cost;
                        }

/*--------------------------------------------------------------------------------------------------------*/
                    }

                }

            }

        }

        ans
=inf;
        
for(i=0;i<=n;i++)
        
{
            
for(j=0;j<=m;j++)
            
{
                
for(zt=0;zt<4;zt++)
                
{
                    
if(dp[i][i+1][j][j+1][zt]!=-1&&dp[i][i+1][j][j+1][zt]<ans)
                        ans
=dp[i][i+1][j][j+1][zt];
                }

            }

        }

        printf(
"%d\n",ans);
    }

    
return 0;
}