UVA 301 POJ 1040- Transportation DFS 回溯

来源:互联网 发布:vb.net 创建文件夹 编辑:程序博客网 时间:2024/05/21 18:39

这道题在UVA过了 但是在POJ上超时了  POJ1040  想一下另外一种算法怎么才能更快的计算出答案

POJ讨论中的优化思路

这道题感觉是个很好的 DFS 题目。 在车站一条线上进行搜索,回溯。然而,如果不进行优化剪枝的话,肯定会TLE,我在本机使用前面一位同学提供的数据,直接运行了一下你的程序,大约要2秒钟。。。优化可以这么做:  1.calss A中可以增加两个域:        P---表示本次order的总价值,它等于  (终点-起点)*人数        R---表示选择本order后,剩余价值--即最多还可得到多大收益  2.读入n,m,l,对P降序排列后,在计算各个order的R,这样很明显的    结论就是:       假若我在某个车站展开DFS,如果"当前收益+该节点的R<max"则       直接在这个节点return,无需再往下搜索。就是在你的DFS循环       里的flag前面加上:if(total+p[i].R < max) return;   本机运行了一下,速度很快。 这里运行一下46ms   不知是否还能再进行优化剪枝?   或者使用C的输入输出,速度更快一点15ms,但这没啥意义。。。。。

UVA  POJ代码


#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int maxn = 100;int N,M,NUM,MAX,Length,L;int station[maxn],vis[maxn],sp[maxn];struct ORDER{    int st,ed,money,num;}order[maxn];void DFS(int S,int money,int Begin)///当前站点  当前钱数  开始递归计算的起点{    if(money > MAX)MAX = money;    if(S >= M)return ;    for(int i = Begin; i < Length; i++)    {        if(order[i].st == S && vis[i] == 0)        {            int f = 1,minn = 0;            for(int j = S; j < order[i].ed; j++)            {                if(station[j] < order[i].num) f = 0; ///如果当前站的容量小于此订单人数就舍去 不处理当前订单  处理下一个订单            }            //if(sp[order[i].st] + money < MAX) f = 0;///加上这个优化  在UVA 过了 POJ也过了  547ms  但是还以再优化  继续想            if(f == 1)            {                for(int j = S; j < order[i].ed; j++)                {                    station[j] -= order[i].num;///当前订单从起点到终点(不包含终点)每个站的容量减去当前订单人数                }                vis[i] = 1;                DFS(S,money + order[i].money, i +1);                vis[i] = 0;                 ///状态复原                for(int j = S; j < order[i].ed; j++)                    station[j] += order[i].num;            }        }        else            if(order[i].st > S)break;    }    DFS(S+1,money,Begin);///当前站没有可取的了  从下一个站开始DFS}int main(){    #ifdef LOCAL    freopen("in.txt","r",stdin);    #endif // LOCAL    while(scanf("%d%d%d",&N,&M,&Length))    {        if(N == 0 && M == 0 && Length == 0)break;        for(int i = 0; i <= M; i++)        {            station[i] = N;            sp[i] = N * (M - i);        }        memset(vis,0,sizeof(vis));///初始化每个站的容量为最大   并标记都没有访问过        for(int i = 0 ;i < Length; i++)        {            scanf("%d%d%d",&order[i].st,&order[i].ed,&order[i].num);            order[i].money = (order[i].ed - order[i].st) * order[i].num;        }        MAX = 0;        /*sort(order,order+Length,cmp);///结构体排序  为DFS做基础*////啊啊啊  次奥  sort排序不稳定  RE无数次        for (int i = 0;i < Length-1; i++)            for (int j = i+1;j < Length; j++)            {                if (order[i].st > order[j].st)                {                    int t;                    t = order[i].st; order[i].st = order[j].st; order[j].st = t;                    t = order[i].money;  order[i].money = order[j].money;   order[j].money = t;                    t = order[i].ed;   order[i].ed = order[j].ed;     order[j].ed = t;                    t = order[i].num;   order[i].num = order[j].num;     order[j].num = t;                }          }        ///因为开车的顺序是从小到大的  不会出现逆序的情况  所以按起点排序        DFS(0,0,0);        printf("%d\n",MAX);    }    return 0;}


0 0