uva757 - Gone Fishing(貪心)

來源:互聯網
上載者:User

標籤:http   io   for   代碼   ar   時間   line   new   

題目:uva757 - Gone Fishing(貪心)


題目大意:有N個湖泊只有一條通路將這些湖泊相連。每個湖泊都會給最開始5分鐘間隔內可以調到的魚(f),然後給每過5分鐘減少的魚的數量(d),如果當前的魚少於等於減少的數量,說明在下個5分鐘沒有魚。還有過每條道路的所要耗費的時間(N-1),時間都是以5分鐘為單位的。漁者可以在任意一個湖泊釣魚,但是起始位置是在湖泊1。問H小時後,漁者怎樣合理的在每個湖泊分配時間,可以得到的魚最多。如果得到最多的魚的方式有多種,則取在前面的湖泊耗時最久的那一種。


解題思路:因為這些湖泊是由一條通路串起來的,這樣就意味著經過湖泊3,那麼的先經過湖泊2。

                  所以這裡先枚舉釣魚的終點i,這樣在路上耗費的時間就可以確定了,然後在0 - i這些湖泊中以f最大的排序。每次取都是f取最多的,直到和這個湖泊的魚減少到和第二個大的f相等或者更小。這裡有個注意點,兩個湖泊如果f相同的話,應該先選比較前面的湖泊。

                 然後再進行排序,重複這些操作直到時間耗盡,或是沒有湖泊有魚。

                這樣就可能存在時間沒有用完的情況,這個時候任意的湖泊都是沒有魚的,在哪個湖泊獃著都是一樣的,但是因為要求的前面的湖泊耗時多,所以剩下的時間就都給湖泊1。

                最後統計魚的時候,大於當前的最大值自然要儲存這種分配方式,但是等於的話,就需要選擇前面湖泊耗時較大的那種。

                計算魚的數量時候要細心。


代碼:

#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int N = 30;int h, n;int t[N];typedef long long ll;ll fish;struct Lake {int i;ll f;int d;int hour;}l[N], l1[N];int cmp (const Lake &a, const Lake &b) { if (a.f == b.f)return a.i < b.i;return a.f > b.f; }int cmp1 (const Lake &a, const Lake &b) { return a.i < b.i; }void init () {h *= 12;fish = -1;for (int i = 0; i < n; i++)l[i].hour = 0;}bool judge (int num, int newh) {          //相同魚的數目的時候比較選擇哪種方案sort (l1, l1 + num + 1, cmp1);l1[0].hour += newh;for (int i = 0; i <= num; i++)if (l1[i].hour != l[i].hour)return l1[i].hour > l[i].hour;return false;}void solve () {init ();int newh;int k, max_day;ll sum; for (int i = 0; i < n; i++) {            //枚舉終點newh = h;for (int j = 0; j <= i; j++) {   l1[j].i = l[j].i;l1[j].f = l[j].f;l1[j].d = l[j].d;l1[j].hour = 0;}for (int j = 0; j <= i - 1; j++)  //路上要耗費的時間newh -= t[j];if (newh <= 0)continue;                 //到達不了直接下一種方案if (i == 0) {                     l1[i].hour += newh;newh = 0;}while (newh > 0 && i) {              //找f最大的湖泊sort (l1, l1 + i + 1 , cmp);       if (l1[0].f == 0)break;if (l1[0].d != 0) {if (l1[0].f == l1[0].f)k = 1;else {k = (l1[0].f - l1[1].f) / l1[0].d;if ((l1[0].f - l1[1].f) % l1[0].d)k++;}}elsek = newh;           //如果d等於0說明這裡的魚不會減少,自然剩下的時間都耗費在這裡最合理。if (newh - k < 0)           k = newh;newh -= k;l1[0].f -= k * l1[0].d;    //更新f和這個湖泊的耗時if (l1[0].f < 0)l1[0].f = 0;l1[0].hour += k;}sum = 0;for (int j = 0; j <= i; j++) {    //計算魚的數目k = l1[j].i;if (!l1[j].hour)continue;if (l[k].d == 0) {sum += l[k].f * l1[j].hour;continue;}max_day = l[k].f/ l[k].d;if (l[k].f % l[k].d != 0)max_day++;if (l1[j].hour <= max_day) max_day = l1[j].hour;l1[j].f = l[k].f - (max_day - 1) * l[k].d;sum += (l[k].f + l1[j].f) * max_day / 2;}if (sum > fish || (sum == fish && judge(i, newh))) {  //維護最大值 fish = sum;for (int j = 0; j <= i; j++) {if (l1[j].i == 0)l[0].hour = l1[j].hour + newh;elsel[l1[j].i].hour = l1[j].hour;}}}}int main () {bool flag = 0;while (scanf ("%d", &n) && n) {if (flag)printf ("\n");flag = 1;scanf ("%d", &h);for (int i = 0; i < n; i++)scanf ("%lld", &l[i].f);for (int i = 0; i < n; i++)scanf ("%d", &l[i].d);for (int i = 0; i < n - 1; i++)scanf ("%d", &t[i]);for (int i = 0; i < n; i++)l[i].i = i;solve();printf ("%d", l[0].hour * 5);for (int i = 1; i < n; i++) printf (", %d",l[i].hour * 5);printf ("\n");printf ("Number of fish expected: %lld\n", fish);}return 0;}


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.