poj 1040 DFS

与网上其他DFS解法相似,但通过for循环实现是否接单:

大致思路相似:维持一个数组存储当前搜索状态的载客量,用takeOrder()函数实现两个功能:1.判断能否接单2.若能则改变状态,同时对于负的载客直接改变状态用于回溯,dfs()中用for循环遍历订单并且通过参数设置不会搜索已经搜过的订单,具体的实现方法见代码,运行时间大概800ms

#include<iostream>
#include<cstdio>
#include<cstring>
#define mem(a,b) memset(a, b, sizeof(a))
#define maxo 22*8 + 100
using namespace std;

int cap, num, nOrder;
int maxEarn;
int orderRecord[maxo];
bool vis[maxo];

struct Order{
    int start, end;
    int num;
}Or[maxo];

bool takeOrder(int s, int e, int n){//判断能否接单,若能则改变orderRecord
    if(n > 0){
        for(int i = s; i < e; i++){
            if(orderRecord[i] + n > cap)
                return false;
        }
    }
    for(int i = s; i < e; i++){
        orderRecord[i] += n;
    }
    return true;
}

void dfs(int oid, int curEarn){
    if(oid >= nOrder) return;
    int increaseEarn;
    for(int i = oid; i < nOrder; i++){
        if(takeOrder(Or[i].start, Or[i].end, Or[i].num)){
            increaseEarn = (Or[i].end - Or[i].start) * Or[i].num;
            if(curEarn + increaseEarn > maxEarn)
                maxEarn = curEarn + increaseEarn;
            dfs(i+1, curEarn + increaseEarn);
            takeOrder(Or[i].start, Or[i].end, -Or[i].num);
        }
    }
}

int main(){

    while(~scanf("%d%d%d", &cap, &num, &nOrder) && cap+num+nOrder!=0){
        for(int i = 0; i < nOrder; i++){
            scanf("%d%d%d", &Or[i].start, &Or[i].end, &Or[i].num);
        }
        mem(vis, false);
        mem(orderRecord, 0);
        maxEarn = 0;
        dfs(0, 0);
        printf("%d\n", maxEarn);
    }

    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值