模拟题。
给你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;
}