貪心問題_魚塘釣魚

魚塘釣魚

【問題描述】

現在有n個魚塘(2<= n<=25),這些魚塘分佈在一條直線上,該路線是單向的(只能前進不能後退)。並且只能從一個魚塘到另一個與之相鄰的魚塘(比如:要從1號魚塘到達3號魚塘,只能" 1 —> 2 —> 3 ",不能 " 1 —> 3 ")
突然有一天,楊過養的那隻大雕肚子餓了,於是楊過決定去釣魚,在繳納一筆揹着小龍女偷偷藏起來的私房錢之後,魚塘主人同意,他可以有h個小時(1<=h <=16)的時間在n個魚塘釣魚(2<= n <=25)。 但是魚塘主人不可能做虧本買賣,所以他給魚塘設置了機關:
1、在最初的5分鐘,i號魚塘預計釣到魚的數量爲 f[i] ( f[i] > 0 )。之後每隔5分鐘,預計釣到魚的數量按 d[i](d[i]>0)遞減。而且,當某段時間的 f[i]<=d[i]時,在下一段時間就釣不到魚了。
2、不止釣魚花時間,在去魚塘的路上也要花時間,規定5分鐘爲一個單位。例如:t[3] = 4,就是說從3號魚塘到4號魚塘所花時間爲
4個單位時間,也就是 4*5=20 分鐘。( 0<= t[i] <=190)

現在楊過很苦惱,希望江湖裏的各位俠士能幫幫他解決這個問題,想出一條錦囊妙計,讓他可以用h小時的時間在n個魚塘裏釣到最多的魚。

【輸入數據】

第一行一個數字:n // 表示有n個魚塘
第二行一個數字:h // 表示有h個小時
第三行n個數字:f[1]、f[2]、…、f[n] // 表示每個初始預計的釣魚數
第四行n個數字:d[1]、d[2]、…、d[n] // 表示每個魚塘每5分鐘預計釣魚數少多少
第五行n-1個數字:t[1]、t[2]、…、t[n-1] // 表示換魚塘所需時間
輸入案例1:
2
1
10 1
2 5
2
輸入案例2:
4
4
10 15 20 17
0 3 4 3
1 2 3
輸入案例3:
4
4
10 15 50 30
0 3 4 3
1 2 3
0

【輸出數據】

數據有兩行:
第一行輸出錦囊妙計:輸出在每個魚塘的釣魚時間
第二行輸出一個數字:輸出最大釣魚數
輸出案例·1:
45 5
31
輸出案例2:
240 0 0 0
480
輸出案例3:
115 10 50 35
724

【具體代碼】

#include<iostream>
#include<cstring>
using namespace std;

int h,n;   // 時間、魚塘數
int f[1025],d[1025],t[1024];  // 初始預計釣魚數、遞減差、換魚塘時間
int plan[1024];  // 釣魚計劃
int best = 0;  // 最大收穫值

void Greedy(int m,int time){  // 用time個單位的時間去釣 1到m 魚塘的魚,並且收穫最大
    if(time<=0)
        return;

    int fish[1024]; // 記錄每個湖此時在單位時間內可以釣到多少魚
    int p[1024];

    for(int i=1; i<=m; i++)
        fish[i] = f[i];

    memset(p,0,sizeof(p));

    int t = 0;  // 釣魚總數
    for(int i=1; i<=time; i++){  // 判斷每個單位時間在哪裏釣魚
        int maxx = 0;  // 最大的預計釣魚數
        int id = 0;    // 對應的魚塘編號

        for(int j=1; j<=m; j++){
            if(fish[j]>maxx && fish[j]>0){  // 比較最大值
                maxx = fish[j];
                id = j;
            }
        }

        if(id!=0){  // 表示該單位時間釣到魚了,每浪費時間
            ++p[id];
            fish[id]-=d[id];
            t+=maxx;
        }else{  // 此時表示還有時間,但是無魚可釣了。
            ++p[1];
        }
    }

    if(t>best){
        best = t;
        memset(plan,0,sizeof(plan));
        for(int i=1; i<=m ; i++){
            plan[i] = p[i];
        }
    }

}

int main()
{
    cin>>n>>h;  // 魚塘數,時間
    for(int i=1; i<=n; i++) cin>>f[i];  // 預計釣魚數
    for(int i=1; i<=n; i++) cin>>d[i];  // 遞減數
    for(int i=1; i<n; i++) cin>>t[i];   // 走路時間

    // 5分鐘一個單位
    int l = h * 12;
    int time = 0;
    for(int i=1; i<=n; i++){
        Greedy(i,l-time);
        time+=t[i];
    }

    for(int i=1; i<=n; i++){
        cout<<plan[i]*5<<" ";
    }
    cout<<endl<<best;

   return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章