宝藏探索(Gone fishing)

描述

旅行者今天有h小时的空闲时间,于是想去提瓦特大陆上探索秘境。

在提瓦特大陆上有n个秘境,(旅行者从秘境1出发),不同的秘境间有元素能量路径连接,可以从第i个秘境到第i+1个秘境,并且花费的时间为ti*5分钟(用以解除秘境间的元素保护力量)。

根据旅行者多年的探索经验,对于秘境i,在最初的5分钟内预计能够获取的宝藏数量为fi,而随着探索时间的增长,每过5分钟,下一个5分钟区间内预计能够发现的宝藏数量就会以一个恒定的速率di减少。直到该秘境中的宝藏被完全回收,就不会再有宝藏了。

请问,旅行者应该怎样安排时间,来获取最多的宝藏呢(探索各个秘境所花的时间必须是5的倍数)。

输入

有多个实例,每个实例(5行):

第一行是整数n个秘境

第二行h空闲时间。

第三行是n个整数指定fi(最初5分钟能获取的宝藏数量)

第四行是n个整数di(宝藏数量的递减速率)

第五行是一行n-1个整数ti(1 <= i <= n - 1,元素能量路径解除保护所需时间)

输入以n=0的情况结束。

输出

对于每个实例,输出两行:第一行:每个秘境的探索时间,用空格分隔。第二行:期望获取宝藏数量。

如果有多个结果(策略),则选择在编号小的秘境停留尽可能久的结果(策略)。

各个实例之间加空行。

输入样例 1
2 
1 
10 1 
2 5 
2 
4 
4 
10 15 20 17 
0 3 4 3 
1 2 3 
4 
4 
10 15 50 30 
0 3 4 3 
1 2 3 
0 
输出样例1
45 5
31

240 0 0 0
480

115 10 50 35
724

思路:贪心

首先枚举:路程是单向的,枚举旅行者在第m个秘境停止,则其在路途中花费的时间就是确定的

贪心:考虑最优子结构,每次选择宝藏最多的秘境收集一次宝,对于任何时刻每个秘境宝藏的数目只与旅行者在这里收集的次数有关

代码实现

cpp 复制代码
#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
int f[30]={0},t[30]={0};
int d[30]={0},stay[30]={0};
int best=0;
void Greed(int pos,int time)
{
    if(time<=0)return;
    int p[30]={0};
    int Realm[30]={0};
    int gain=0;
    for(int i=0;i<30;i++)
        Realm[i]=f[i];//拷贝一份用于贪心算法
    for(int i=0;i<time;i++)
    {
        int Max=0,id=-1;
        for(int j=0;j<=pos;j++)
        {
            if(Realm[j]>Max)
            {
                Max=Realm[j];id=j;
            }
        }
        if(id!=-1)
        {
            p[id]+=1;
            gain+=Realm[id];
            Realm[id]-=d[id];
        }
        else p[0]+=1;//编号小的秘境停留尽可能久
    }
    if(gain>best)
    {
        memset(stay,0,sizeof(stay));
        best=gain;
        for(int i=0;i<30;i++)stay[i]=p[i];
    }
    return;
}
int main()
{
    int n=1;
    cin>>n;
    while(n!=0)
    {
        int h;
        cin>>h;
        h*=60/5;//以5分钟为收一次宝的时间
        for(int i=0;i<n;i++)scanf("%d",&f[i]);
        for(int i=0;i<n;i++)scanf("%d",&d[i]);
        for(int i=1;i<n;i++)scanf("%d",&t[i]);
        
        int time=0;
        best=-1;
        for(int i=0;i<n&&h-time;i++)
        {
            time+=t[i];
            Greed(i,h-time);
        }
        bool flag=false;
        for(int i=0;i<n;i++)
        {
            if(flag)printf(" ");
            else flag=true;
            printf("%d",stay[i]*5);
        }
        printf("\n%d\n\n",best);
        cin>>n;
    }
    return 0;
}

这题注意格式,每一行不要留空格

相关推荐
代码雕刻家26 分钟前
数据结构-3.9.栈在递归中的应用
c语言·数据结构·算法
雨中rain26 分钟前
算法 | 位运算(哈希思想)
算法
Kalika0-02 小时前
猴子吃桃-C语言
c语言·开发语言·数据结构·算法
sp_fyf_20242 小时前
计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-10-02
人工智能·神经网络·算法·计算机视觉·语言模型·自然语言处理·数据挖掘
我是哈哈hh4 小时前
专题十_穷举vs暴搜vs深搜vs回溯vs剪枝_二叉树的深度优先搜索_算法专题详细总结
服务器·数据结构·c++·算法·机器学习·深度优先·剪枝
Tisfy4 小时前
LeetCode 2187.完成旅途的最少时间:二分查找
算法·leetcode·二分查找·题解·二分
Mephisto.java4 小时前
【力扣 | SQL题 | 每日四题】力扣2082, 2084, 2072, 2112, 180
sql·算法·leetcode
robin_suli4 小时前
滑动窗口->dd爱框框
算法
丶Darling.4 小时前
LeetCode Hot100 | Day1 | 二叉树:二叉树的直径
数据结构·c++·学习·算法·leetcode·二叉树
labuladuo5205 小时前
Codeforces Round 977 (Div. 2) C2 Adjust The Presentation (Hard Version)(思维,set)
数据结构·c++·算法