UVA 301 Transportation

 

第一次我理解错了题目,以为是最长路径问题,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;
}

 

 

你可能感兴趣的:(port)