HDU 5191

这是不知道什么类型的题。。。或许应该算。。。技巧型的???

刚开始的时候暴力,然后T掉了,后来想了想,改了一下,又wa掉了。。。。

先说下错误的想法:分了两类讨论,一类是n>w,一类是n<=w的。第一类想说,要保证扫描到的序列就是所求序列,所以内部先分配,多余的抛出去就好了,这一部分没有问题。但是到了第二类的时候,因为要创建新的堆,所以出现了一种问题,内部多余的,是分配出去(n-w+1)个,还是(n-w)个?这里剩余的值一直有问题。以为可以分配的好,但是实际上这类的讨论若是这种方式是不能正确解得的。


后来看了题解,很简单,就是在前后都加上了w个空位。然后用第一类的方法解得即可。

有感,,,算法应该是问题的统一讨论,既然对于第一类问题有了方法,为什么不想着把这个方法扩展到第二类中。还是太蠢了QAQ

#include <stdio.h>
#define maxn 301000
#define max 9999999999999
#define ll long long               //这里要注意把数据范围改改,因为50000*50000貌似会爆int
int b[maxn];
ll sum[maxn];
int n,h,w;
ll min(ll a,ll b)
{
    return a<b?a:b;
}
int main()
{
    while(scanf("%d%d%d",&n,&w,&h)!=EOF)
    {
        int i;
        ll j,k;
        ll ans=max;
        for(i=0;i<w;i++) sum[i]=b[i]=0;
        for(i=w;i<n+w;i++)
        {
            scanf("%d",&b[i]);
            sum[i]=sum[i-1]+b[i];
        }
        for(i=n+w;i<n+w+w;i++) sum[i]=sum[i-1],b[i]=0;
        j=k=0;
        k=(w*h);
        for(i=1;i<n+w;i++)
        {
            int tmp=b[i-1]-h;
            if(tmp>0) j-=tmp;
            else k+=tmp;
            tmp=b[i+w-1]-h;
            if(tmp>0) j+=tmp;
            else k-=tmp;
            ll res=sum[i-1]+sum[n+w+w-1]-sum[i+w-1];
            if(j>=k) ans=min(ans,j);
            else
            {
                if(res>=(k-j)) ans=min(ans,k);
                else continue;
            }
            //printf("%lld  %lld  %lld\n",j,k,res);
        }
        printf("%lld\n",ans==max?-1:ans);
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值