uva301 - Transportation

来源:互联网 发布:星际淘宝网最新章节 编辑:程序博客网 时间:2024/06/09 14:29

第一次交,直接dfs超时。2^22这个数还是挺大的,所以得考虑剪枝。题剪枝的办法是在检查到一张票的时候,把剩下票的所有的利润值都试着累加起来再加上此刻的利润,跟之前存储的最大利润进行比较,如果最大利润还是比较大的话,那么就没有必要再递归下去了,反正最好的情况加起来都没有当前的最大利润大。

                                                                                                                          -----------------------摘自http://www.cnblogs.com/liaoguifa/archive/2013/04/25/3043183.html

#include <iostream>#include <cstring>#include<cstdio>#include<cstdlib>#include <string>#include<algorithm>//#define MARK -2147483647using namespace std;int cityn,ordn,capa,ans;int lirun[30];struct ding{    int s,t,num;int flag;};bool com(ding a,ding b){    return a.s<b.s;}ding d[30];void dfs(int num,int ordi,int price){    int i;    if(ordi==ordn){if(price>ans) ans=price;return; }    int num1=num;    for(i=0;i<ordi;++i)    {        if(d[ordi].s>=d[i].t&&d[i].flag){num1=num1-d[i].num; }    }    if(ans>price+lirun[ordi])return;    if(num1+d[ordi].num>capa)    {dfs(num,ordi+1,price);}    else    {           dfs(num,ordi+1,price);       //1       1移到2处并没有时间减少,本来以为先选,比先不选快。                d[ordi].flag=1;                dfs(num+d[ordi].num,ordi+1,price+(d[ordi].t-d[ordi].s)*d[ordi].num);                d[ordi].flag=0;                                                                 //2    }return;}int main(){// freopen("in.txt","r",stdin);    while(scanf("%d%d%d",&capa,&cityn,&ordn))    {        ans=0;        if(!cityn&&!capa&&!ordn)break;        int i;        for(i=0;i<ordn;++i)        {            scanf("%d%d%d",&d[i].s,&d[i].t,&d[i].num);            d[i].flag=0;        }        sort(d,d+ordn,com);lirun[ordn-1]=(d[ordn-1].t-d[ordn-1].s)*d[ordn-1].num;        for(i=ordn-2;i>=0;--i){lirun[i]=lirun[i+1]+(d[i].t-d[i].s)*d[i].num; }        dfs(0,0,0);        printf("%d\n",ans);    }    return 0 ;}


 

原创粉丝点击