构建双塔(dp-双进程)

这里写图片描述

f[i][j] 表示取前i块水晶、两塔差为j时较高塔的最大高度。

注意,这里的f[i][j]都是从上一阶段推得的。我们在面对第i块水晶时,它可能是从以下四种决策得来的:

f[i][j]=max(f[i-1][j]) ; 这块水晶被丢掉了。

f[i][j]=max(f[i-1][j+h[i]]) ; 这块水晶被给了上一个状态中较低的那座塔,且它未超过较高的塔,由图可知较高塔的最大高度是不变的。
这里写图片描述

f[i[][j]=max(f[i-1][j-h[i]]+h[i]) ; 这块水晶被给了上一个状态中较高的塔,由图可知,较高塔的值增加了h[i]。当然,此时我们要保证j>h[i]。

这里写图片描述
f[i][j]=max(f[i-1][h[i]-j]+j) ;这块水晶被给了上一阶段较低的塔,且它超过了较高塔。由图可知,较高塔的值增加了j。
这里写图片描述

美妙的code时间:

void init()
{
    read(n); 
    for(int i=1;i<=n;++i) read(h[i]),summ+=h[i];
}

void work()
{
    memset(f,-10,sizeof(f));//起初所有状态不合法 。 
    f[0][0]=0;
    for(int i=1;i<=n;++i)
        for(int j=0;j<=summ;++j)
        {
            f[i][j]=max(f[i-1][j],f[i-1][j+h[i]]);
            if(j>=h[i]) f[i][j]=max(f[i][j],f[i-1][j-h[i]]+h[i]);
            else f[i][j]=max(f[i][j],f[i-1][h[i]-j]+j);
        }
    if(f[n][0]) printf("%d",f[n][0]);//放了n块水晶且两塔差==0时即为所求。 
    else printf("Impossible");
}

起初看这题的时候存在误区,将f[i-1][j+h[i]]理解为把水晶给了当前的较高塔,实际上这样就不符合f[i][j]的设定了。应是上一状态对这一状态有影响。还是没有深刻理解状态转移的含义啊。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值