UVa 301 – Transportation

來源:互聯網
上載者:User
301 - Transportation 4584 32.83% 1338 76.08%

題目連結:

http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=108&page=show_problem&problem=237

題目類型: 回溯法

原題:

Ruratania is just entering capitalism and is establishing new enterprising activities in many fields including transport. The transportation company TransRuratania is starting a new express train from city
A to city B with several stops in the stations on the way. The stations are successively numbered, city A station has number 0, city B station number m. The company runs an experiment in order to improve passenger transportation capacity and thus
to increase its earnings. The train has a maximum capacity n passengers. The price of the train ticket is equal to the number of stops (stations) between the starting station and the destination station (including the destination station). Before
the train starts its route from the city A, ticket orders are collected from all onroute stations. The ticket order from the station S means all reservations of tickets from S to a fixed destination station. In case the company cannot accept all orders because
of the passenger capacity limitations, its rejection policy is that it either completely accept or completely reject single orders from single stations.

Write a program which for the given list of orders from single stations on the way from A to B determines the biggest possible total earning of the TransRuratania company. The earning from one accepted
order is the product of the number of passengers included in the order and the price of their train tickets. The total earning is the sum of the earnings from all accepted orders.

Sample Input

10 3 40 2 11 3 51 2 72 3 1010 5 43 5 102 4 90 2 52 5 80 0 0

Sample Output

1934

題目大意:

有一家運輸公司, 運營一段鐵路, 該鐵路A 站到B站。 從A站開始到B站編號為0....N-1。 

每輛火車的限載人數為n人, 車票的價錢按站數計算,搭一個站收1元, n個站即n元。

為了讓收益最大化, 每次開車前,都會先分析所有的車票,相同起點和終點的歸為同一個訂單。因為人數限制,如果人數太多的

話,就必須要放棄一些訂單。 這個公司的做法有點極端, 要麼整個訂單都放棄,要麼整個訂單都接受。

編寫一個程式,輸出最大能收入多少錢。

分析與總結:

這題讓我吐血TLE了無數次。

原因在於,按照慣性思維,和處理全排列的一樣了, 開了個vis數組,然後遞迴遍曆所有可能。而這一題和全排列不一樣,

全排列是所有點最終都會訪問到的,所以開vis數組標記很有必要,但是這題因為有些訂單是不要的,對於不要的訂單,以後都不會再去訪問它, 而因為之前沒有訪問,所以vis數組上對它的記錄還是停留在沒有訪問的狀態,所以以後每次的遞迴都會再次去試探一下那些不要的訂單,而試探的時候又要判斷是否會超載,所以浪費的時間是十分巨大的!

所以,我就一直被催地TLE..............

解決這個問題, 可以不用開vis數組。 遞迴時,只往前面搜尋,前面已經訪問過的都不要回頭再去訪問一便,所以訪問到的一定是沒有訪問過的。在遞迴函式中有一個參數cur, 表示的是當前要從數組中的那一個元素開始搜尋, 然後這一次的遞迴就從那之後開始進行搜尋。

如何表示車上的人數,檢查是否超載? 我是開了一個mark數組, 這個數組表示各個站上有多少人。每增加一個訂單時,就把

這個訂單的人數加到它的起始站到終點站(不包含終點站)上。 然後下次要檢查是否超載時,就看這次加了人數之後,會不會有

超過限載人數的即可。

#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>#define MAXN 300using namespace std;int n, no_B, numTicket, maxSum, mark[MAXN], last[MAXN];int status[MAXN];struct Ticket{    int start, end, num;    int earn;    int leftSum;}arr[MAXN];void dfs(int cur, int sum){    if(sum > maxSum){        maxSum = sum;    }    for( ; cur<numTicket; ++cur){        int i;        // 剪枝,如果剩下的都加上還比最大的小,直接退棧        if(sum+arr[cur].leftSum < maxSum) return;         for(i=arr[cur].start; i<arr[cur].end; ++i){            mark[i] += arr[cur].num;            if(mark[i] > n) break; // 如果超過限載的話        }        if(i==arr[cur].end){ // 沒有超過限載            dfs(cur+1, sum+arr[cur].earn);            --i;        }        for( ; i>=arr[cur].start; --i){            mark[i] -= arr[cur].num;        }    }}  int main(){#ifdef LOCAL    freopen("input.txt","r",stdin);#endif    int order;    while(scanf("%d %d %d", &n, &no_B, &order)!=EOF){        if(!n && !no_B && !order) break;        numTicket = 0;        int a,b,c;        for(int i=0; i<order; ++i){            scanf("%d %d %d", &a, &b, &c);            if(c <= n){ // 人數大於限制人數的訂單不考慮                arr[numTicket].start=a, arr[numTicket].end=b, arr[numTicket].num = c;                arr[numTicket].earn = (b-a)*c;                arr[numTicket++].leftSum = (b-a)*c;            }        }        for(int i=numTicket-2; i>=0; --i)            arr[i].leftSum += arr[i+1].leftSum;        memset(vis, 0, sizeof(vis));        memset(mark, 0, sizeof(mark));        maxSum = -2147483646;        dfs(0, 0);                printf("%d\n", maxSum);    }    return 0;}


——  生命的意義,在於賦予它意義。

 

                原創  http://blog.csdn.net/shuangde800  , By
  D_Double  (轉載請標明)


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.