soj3343:Tower

本文详细解析了SOJ3343 Tower问题,通过两种不同的算法思路探讨如何计算给定数量及尺寸的稻草包能够堆叠的最大高度。作者分享了从错误尝试中汲取的经验,并最终提出了一种有效的解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

首先这道题我WA了十次,捂脸

这道题不是贪心啊,soj分类给它归到贪心了,考虑了一下不知道怎么搞,大概,,不是贪心吧

前几次wa是因为题意都没看完就开始写,然后理解错题意就哇了,后几次我到现在还不大明白为什么wa,希望有大佬给我讲讲。

soj 3343:Tower

http://acm.scu.edu.cn/soj/problem.action?id=3343

简述题意,一共有N包稻草,每包棱宽不同,从1-N由传送带送进来,必须按照循序拜访,先摆一层,后二层,再三层,不可逆,已知所有N包棱宽,问最高可以摆多高。

我的错误代码如下:

#include<cstdio>
#include<cstring>
#define MAX 100010
int hay[MAX];
int sum[MAX];

int main()
{
    int num;
    while(~scanf("%d",&num))
    {
        memset(hay,0,sizeof(hay));
        memset(sum,0,sizeof(sum));

        int height = 1;
        for(int i = 0; i < num; i++)
            scanf("%d",&hay[i]);
        if(num == 0)
        {
            printf("0\n");
            continue;
        }

        sum[height] = hay[num-1];
        int a = 0;
        for(int j = num-2 ; j>=0 ; j--)
        {
            a += hay[j];
            if(a >= sum[height])
            {
                ++height;
               // printf("1 height=%d,a=%d\n",height,a);
                sum[height] = a;
                a = 0;
            }
            else if(j == 0)
            {
                sum[height] += a;
               // printf("2 height=%d,a=%d\n",height,a);
            }

        }
        printf("%d\n",height);
    }
    return 0;
}
我的想法是,倒着看,第N包肯定放在最上面一层,记为1层吧,然后看接下来的包是否>上一层的宽,如果否,则再加上下一包的宽,循环直到大于宽度,如果一直到最后一包都没大于,那就层数不增加。大佬们帮我瞅瞅哪里不对

wa了那么多次肯定得换一种方法了,那就如下:

#include <cstdio>
#include <cstring>
#define MAX 100000+10
using namespace std;
int hay[MAX],top[MAX],height[MAX];

int main()
{
    int num;
    while (~scanf("%d",&num))
    {
        for(int i=0;i < num; i++)
            scanf("%d",&hay[i]);

        memset(top,0,sizeof(top));
        memset(height,0,sizeof(height));

        for (int i = num-1;i >= 0; i--)
        {
            int j = i+1;
            int tmp = hay[i];
            while (tmp < top[j])
            {
                //printf("1top[j]=%d tmp=%d,j=%d\n",top[j],tmp,j);
                tmp += hay[j++];
                //printf("2top[j]=%d tmp=%d,j=%d\n",top[j],tmp,j);
            }

            top[i] = tmp;
            height[i] = height[j]+1;
            //printf("i=%d top[i]=%d tmp=%d,floor[i]=%d\n",i,top[i],tmp,floor[i]);
        }
        printf("%d\n",height[0]);
    }
    return 0;
}
这个意思是,假设输入a,b,c,(假设123)

先判断c,c和不存在的顶端宽度比,肯定大,所以算一层。

然后b,若b<c,那么b+c(假设bc一层),那么和不存在的c上面的那一层相比,肯定大,也可以算作一层。

然后a,a和(b+c)相比,a<(b+c),那么a+b判断c在的层宽。

也就是

千万注意j的变化!!!!!

为了方便看,把123数组计数先就看成123,不是012,解释一下:

简言之,主体思想就是3在一层height[3] = 1,top[3] = 3,

2比3小,那2肯定不能自己一层,所以2,3先一层吧,height[2]=height[4]+1(第二个数所在楼层,因为第三个数正在和第二个数相加,所以判断再以前的顶宽,也是由这个高度+1),top[2] = 2+3 = 5

1比5小,那考虑1+2=3,和top[3]相比,因为第二个数2现在正在和1相加,所以1+2之和,与第三个数所在顶宽判断大小,1+2=3,那就是height[3]+1=2

简单伐。。。

就是每一次循环,都先把下一个数要比较的上一层宽度先定义出来,top[i],如果i所在这层宽度不对,那就把这个数拉拢到一层,再i+1,看和与之前的数所在层宽大小。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值