hdu4600 Harvest Moon,模拟
自从学了很多莫名其妙、不明所以、看似牛逼比赛却很难想到、想到了又很难打出来、打出来又很难调对的算法之后。。。
我发现我越来越不会做模拟题了。
这个题……就是注意细节吧。
主要有几个:
1.统计一下几种铺的方式各有几个,就可以1000D*1000A暴力模拟了。注意,除了3*3的从左上开始铺满之外,先铺右下角的那种比较优。
2.如果数据不是太水答案是会爆int的。
3.自己注意吧。
自从学了很多莫名其妙、不明所以、看似牛逼比赛却很难想到、想到了又很难打出来、打出来又很难调对的算法之后。。。
我发现我越来越不会做模拟题了。
这个题……就是注意细节吧。
主要有几个:
1.统计一下几种铺的方式各有几个,就可以1000D*1000A暴力模拟了。注意,除了3*3的从左上开始铺满之外,先铺右下角的那种比较优。
2.如果数据不是太水答案是会爆int的。
3.自己注意吧。
没把t[]数组还原,怒wa两发,哎。。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define NN 1010
int t[10];
int w[10];
int sv[10];
void init(int n,int m,int day,int t[],int &tot){
int i,j,tmp,tn,tm;
tn=(n/3)*(m/3);
tot=0;
if (tn!=0) {tot++;t[tot]=tn;w[tot]=9;}//3*3
if (n%3==0||m%3==0){tn=tm=0;} //right bottom
else {
++tot;
t[tot]=1;
if (n>=3) tn=3;else tn=n%3;
if (m>=3) tm=3;else tm=n%3;
w[tot]=tn*(m%3)+tm*(n%3)-(m%3)*(n%3);
}
if (n%3){
++tot;
w[tot]=n%3*3;
tm=m-tm;
t[tot]=tm/3;
if (t[tot]==0) --tot;
if (tm%3){
++tot;
w[tot]=(n%3)*(tm%3);
t[tot]=1;
}
}
if (m%3){
++tot;
w[tot]=m%3*3;
tn=n-tn;
t[tot]=tn/3;
if (t[tot]==0) --tot;
if (tn%3){
++tot;
w[tot]=(tn%3)*(m%3);
t[tot]=1;
}
}
for(i=1;i<=tot;++i){
for(j=i+1;j<=tot;++j){
if (w[i]<w[j]){
tmp=w[i];w[i]=w[j];w[j]=tmp;
tmp=t[i];t[i]=t[j];t[j]=tmp;
}
}
}
}
long long addw[NN];
int addt[NN][10];
long long work(int pb,int ps,int fd,int md,int t[],int tot,int beg,int day){
long long ret=beg,tmp;
int i,j;
memset(addw,0,sizeof(addw));
memset(addt,0,sizeof(addt));
for(i=1;i<=day+1;++i){
ret+=addw[i]*ps;
if (md!=0&&i+md<=day+1) addw[i+md]+=addw[i];
//printf("%d %I64d\n",i,ret);
if (i+fd>day+1) continue;
for(j=1;j<=tot;++j){
if (w[j]*ps<=pb) continue;
t[j]+=addt[i][j];
tmp=ret/pb;
tmp=min(tmp,(long long)t[j]);
ret-=pb*tmp;
t[j]-=tmp;
addw[i+fd]+=w[j]*tmp;
if (md==0) addt[i+fd][j]+=tmp;
}
}
return ret;
}
int cas,n,m,q,day,beg,i,j;
int pb,ps,fd,md;
long long ans;
int tot;
int main(){
//freopen("4600in.txt","r",stdin);
scanf("%d",&cas);
while(cas--){
scanf("%d%d%d%d%d",&n,&m,&q,&day,&beg);
init(n,m,day,t,tot);
for(i=1;i<=tot;++i) sv[i]=t[i];
ans=beg;
for(i=1;i<=q;++i){
scanf("%d%d%d%d",&pb,&ps,&fd,&md);
for(j=1;j<=tot;++j){t[j]=sv[j];}
ans=max(ans,work(pb,ps,fd,md,t,tot,beg,day));
}
printf("%I64d\n",ans);
}
return 0;
}