hdu 4600 Harvest Moon (模拟+贪心)

模拟题。
给你w*h的格子。
a种作物种子,每种种子可以播种至3*3的格子中,可以越界,越界收益无效。
若某格子中仍有作物在生长,那么对它播种无效。
q_i表示购买第i种作物种子的价格。
p_i表示第i种作物成熟之后,卖出每个格子的作物的价钱。
n_i表示第i种作物的成熟天数。
m_i为成熟周期,如果m_i=0,表示该作物收割一次后就消失,可以再次播种。如果m_i不为0,表示该作物收割一次后,每隔m_i天会再次成熟,不需要再次播种。
现在给你y元,d天,从始至终只能使用一种种子种植,问d天后手中最多能有多少钱。

典型的模拟+贪心
1、首先处理网格,统计num[i],表示有多少份种子可以覆盖i个方格。贪心让每次播种尽可能多的覆盖格子。那么先考虑从左上角取3*3的格子,再从右下角取3*3的格子(它拥有当前非完整3 * 3的最大的面积),随后再考虑最右和最下的带状面积。
2、然后枚举i,根据m_i,分别计算即可。

 

#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
using namespace std;

long long T,k,y,w,h,a,d,wx,hx,ans;
long long q[1200],p[1200],n[1200],m[1200],num[10];

long long work1(long long x)
{
    long long time,timex,k,harvest,gettime,money=y;
    long long numx[10],get[1001];
    memset(get,0,sizeof(get));
    for(long long i=1;i<=9;i++)
        numx[i]=num[i];
    for(time=0;time<=d;time++)
    {
        money+=get[time];
        if(time+n[x]>d || money/q[x]==0) continue;
        gettime=1+(d-time-n[x])/m[x];
        harvest=0;
        for(long long i=9;i>=1;i--)
            if(numx[i]>0 && money>0 && gettime*p[x]*i>q[x])
            {
                if(money/q[x]>=numx[i])
                    k=numx[i];
                else
                    k=money/q[x];
                numx[i]-=k;
                money-=q[x]*k;
                harvest+=p[x]*i*k;
            }
        timex=time+n[x];
        get[timex]+=harvest;
        while(timex+m[x]<=d)
        {
            timex+=m[x];
            get[timex]+=harvest;
        }
    }
    return money;
}

long long work2(long long x)
{
    long long k,money=y,time=0,harvest=0;
    while(time<=d)
    {
        harvest=0;
        if(time+n[x]>d) break;
        for(long long i=9;i>=1;i--)
            if(money>0 && p[x]*i>q[x])
            {
                if(money/q[x]>=num[i])
                    k=num[i];
                else
                    k=money/q[x];
                money-=q[x]*k;
                harvest+=p[x]*i*k;
            }
        time+=n[x];
        money+=harvest;
    }
    return money;
}

int main()
{
    cin>>T;
    while(T--)
    {
        cin>>w>>h>>a>>d>>y;
        for(long long i=1;i<=a;i++)
            cin>>q[i]>>p[i]>>n[i]>>m[i];
        memset(num,0,sizeof(num));
        wx=w%3;
        hx=h%3;
        num[9]=(w/3)*(h/3);
        num[9-(3-wx)*(3-hx)]++;
        num[wx*3]+=h/3-1;
        num[hx*3]+=w/3-1;
        num[wx*hx]+=2;
        ans=y;
        for(long long i=1;i<=a;i++)
        {
            if(m[i]!=0)
                k=work1(i);
            else
                k=work2(i);
            if(ans<k) ans=k;
        }
        cout<<ans<<endl;
    }
    return 0;
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值