hdu4600 Harvest Moon,模拟

2 篇文章 0 订阅
hdu4600 Harvest Moon,模拟
自从学了很多莫名其妙、不明所以、看似牛逼比赛却很难想到、想到了又很难打出来、打出来又很难调对的算法之后。。。
我发现我越来越不会做模拟题了。

这个题……就是注意细节吧。
主要有几个:
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;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值