剪枝的艺术(求助
查看原帖
剪枝的艺术(求助
332549
幽灵特工楼主2021/8/9 22:22

CTSC2000

毒瘤搜索题,125MB,4s。 现在搜索得到的答案都对了,求剪枝

#include <bits/stdc++.h>
using namespace std;
int t1, t2, t3, p1, p2;

struct work {//事件
    int time, type, SCV;//事件结束时间,事件类型(采气或采钱,训练SCV),一共几个工人在采集
    work(int a, int b, int c) {
        time = a; type = b; SCV = c;
    }
    bool operator < (work x)const {
        return this->time > x.time;
    }
};

struct SC {//StarCraft,星际争霸
    int Minerals, Vespene_Gas;//晶体矿储量,高能瓦斯储量
    int Time;//中国第一t理赔难(乱入了,其实是当前时间)
    int MineralsWill, Vespene_GasWill;//将要得到的收入
    int SCV;//SCV总量,不管空闲与否
    priority_queue <work> pq;
    SC(int x, int y, int a, work b, int n, int m, int scv) {
        Minerals = x; Vespene_Gas = y;
        Time = a;
        pq.push(b);
        MineralsWill = n; Vespene_GasWill = m;
        SCV = scv;
    }
};
queue <SC> q;
int bfs() {
    int ans = 1e9 + 10;
    q.push(SC(50, 0, 0, work(0, -1, 4), 0, 0, 4));
    while (!q.empty()) {   
        SC sc = q.front();
        q.pop();
        sametimework:;
        int SCV = sc.pq.top().SCV;
        sc.Time = sc.pq.top().time;
        switch (sc.pq.top().type) {
        case -1:break;
        case 1: {sc.Minerals += SCV * 8; sc.MineralsWill -= SCV * 8; break; }
        case 2: {sc.Vespene_Gas += SCV * 8; sc.Vespene_GasWill -= SCV * 8; break; }
        case 3: {SCV++; sc.SCV++; }
        }
        sc.pq.pop();
        if (!sc.pq.empty() && !q.empty())if (sc.pq.top().time == sc.Time)goto sametimework;//同时完成的事件顺手做掉
        //接下来开始新事件
        if (sc.Time >= ans)continue;
        if (sc.Minerals >= p1 && sc.Vespene_Gas >= p2) {
            ans = sc.Time;
            continue;
        }
        if (sc.Minerals + sc.MineralsWill >= p1) {//钱够了
            if (sc.Vespene_Gas + sc.Vespene_GasWill >= p2)continue;//气也够了
            sc.pq.push(work(sc.Time + t2, 2, SCV));
            sc.Vespene_GasWill += SCV * 8;
            q.push(sc);//不造农民,全部采气
            if (sc.Minerals < 50)continue;
            if (sc.SCV * 8 * t2 >= p2)continue;
            sc.Minerals -= 50;
            sc.pq.push(work(sc.Time + t3, 3, 0));
            q.push(sc);//造个农民,全部采气
            //cout << 1 << endl;
            continue;
        }
        if (sc.Vespene_Gas + sc.Vespene_GasWill >= p2)continue;//气也够了
        else {
            int x = min(SCV, (p1 - sc.Minerals - sc.MineralsWill + 7) / 8);//再有x个农民采钱就ok了
            sc.pq.push(work(sc.Time + t1, 1, x));
            if (SCV > x)sc.pq.push(work(sc.Time + t2, 2, SCV - x));
            sc.MineralsWill += x * 8;
            sc.Vespene_GasWill += (SCV - x) * 8;
            q.push(sc);//不造农民,进行采集
            if (sc.Minerals < 50)continue;
            if (sc.SCV * 8 * t1 >= p1)continue;
            if (sc.SCV * 8 * t2 >= p2)continue;
            sc.Minerals -= 50;
            sc.pq.push(work(sc.Time + t3, 3, 0));
            q.push(sc);//造个农民,进行采集
            //cout << 1 << endl;
        }
    }
    return ans;
}
int main()
{
    cin >> t1 >> t2 >> t3 >> p1 >> p2;
    cout << bfs();
}

2021/8/9 22:22
加载中...