第一次我理解错了题目,以为是最长路径问题,YY了N久,发现不对。我发现,它从1-3一定会经过2,而不是简单的最长路径问题,所以我们需要用回溯法来解决。

 

题目意思: 有一辆车从A城市开往B城市,途中有m个站,车上最多的载客人数为n人,每一个站的价格就是终点和起点的差值,现在有k分订单,要求找到这辆车的最大利润。


解题思路: 这一题如果我们去搜索站点,那么情况将会非常糟糕,但是如果我么去搜索订单,那么对于每一个订单而言就是取和不取,那么我们就可以知道这个解空间树的每一层就是一个订单,那么我们只要对这个订单编号,然后搜索订单即可。另外我们开一个数组,专门来存储每一个站点当前的人数,注意这里的人数处理,一份订单进来,那么起点---终点前一站都是要加上的,终点下车不用加,最后恢复现场。

 

CODE:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
using namespace std;

#define MAXN 22

struct node
{
    int u, v, cap;
}a[MAXN];

int A[MAXN];        //保存每个节点的最大存储量 

int ans;
int cap, stops, n;


void init()
{
    ans = 0;
    memset(A, 0sizeof(A));
}

void dfs(int cur, int n)
{
    if(cur == n)
    {
        int tot = 0;
        for(int i = 0; i < stops; i++) tot += A[i];
        if(ans < tot) ans = tot;
    }
    else
    {
        bool ok = 1;
        for(int i = a[cur].u; i < a[cur].v && ok; i++)
            if(A[i] + a[cur].cap > cap) ok = 0;
        if(ok)
        {
            for(int i = a[cur].u; i < a[cur].v; i++) A[i] += a[cur].cap;
            dfs(cur+1, n);     //接收订单 
            for(int i = a[cur].u; i < a[cur].v; i++) A[i] -= a[cur].cap;
        }
        dfs(cur+1, n);         //不接收订单 
    }
}

int main()
{
    while(~scanf("%d%d%d", &cap, &stops, &n) && (cap || stops || n)) //这而写 cap, stops, n就WA.
    {
        init();
        for(int i = 0; i < n; i++)
            scanf("%d%d%d", &a[i].u, &a[i].v, &a[i].cap);
        dfs(0, n);
        printf("%d\n", ans);
    }
    return 0;
}

 

 

posted on 2012-09-27 22:11  有间博客  阅读(370)  评论(0编辑  收藏  举报