codeUp 2031 To fill or not to fill 复杂贪心

本文探讨了在有限油箱容量、多个加油站和不同油价的情况下,如何设计从杭州到目的地的最经济路线。通过分析样例,阐述了贪心策略在解决此类问题中的应用,即在每个加油站选择局部最优策略,最终实现全局最小花费。

2031: To Fill or Not to Fill

时间限制: 1 Sec  内存限制: 32 MB
提交: 599  解决: 132
With highways available, driving a car from Hangzhou to any other city is easy. But since the tank capacity of a car is limited, we have to find gas stations on the way from time to time. Different gas station may give different price. You are asked to carefully design the cheapest route to go.

Input Specification:

Each input file contains one test case. For each case, the first line contains 4 positive numbers: Cmax (<= 100), the maximum capacity of the tank; D (<=30000), the distance between Hangzhou and the destination city; Davg (<=20), the average distance per unit gas that the car can run; and N (<= 500), the total number of gas stations. Then N lines follow, each contains a pair of non-negative numbers: Pi, the unit gas price, and Di (<=D), the distance between this station and Hangzhou, for i=1,...N. All the numbers in a line are separated by a space.

Output Specification:

For each test case, print the cheapest price in a line, accurate up to 2 decimal places. It is assumed that the tank is empty at the beginning. If it is impossible to reach the destination, print "The maximum travel distance = X" where X is the maximum possible distance the car can run, accurate up to 2 decimal places.

Sample Input 1:
50 1300 12 8
6.00 1250
7.00 600
7.00 150
7.10 0
7.20 200
7.50 400
7.30 1000
6.85 300
Sample Output 1:
749.17
Sample Input 2:
50 1300 12 2
7.10 0
7.00 600
Sample Output 2:
The maximum travel distance = 1200.00
 

题意就是从起点到终点有很多的加油站 每个加油站有距离起点的距离和单价 我们从起点开车到终点 开始油量为0 要尽可能走到终点 问所求的最小花费是多少?如果走不到终点 就输出最远距离。

一开始给出油箱大小,到终点的距离,还有每单价油可以走的里程数,以及加油站的信息

 

分析:

由于这个问题逻辑比较复杂 可以先研究样例

假设汽车从起点S到终点E必须通过加一次油到达 可达范围内有多个价格不一的加油站 

如果可达范围内有更便宜的G 我们要选择那个加油站续命 先加够到这个加油站G的油 在到G处加新的油 这样就相当于从起点到G再到终点的松弛 可以通过这个加油站把后面的路程的花费给减小“松弛”掉  

如果选择某个并不是选择可达范围内最靠前的更便宜的加油站去加油站

如果选择了一个较远的,花费更大的站A 那么就必然导致起点加油变多花费变多,从A站新加的油到终点的这段距离花费变多 虽然路程变小 从全局来看 两种不同的选择花费不同的路段里 第二段从G到A花费变多 从A到终点E花费也变多 从而导致全局花费更大

如果选择了一个较近的花费更大的站B 那么从起点S到B花费不变 那么从B到G花费变多 从G到终点花费也变多  从而导致全局更大的花费

所以在当前站 选择可达范围内最近的且更便宜的能够带来更小的局部最优 从而获得更小的全局花费

如果没有更便宜的 

那么就要在初始S加满 这样才能尽可能少加更贵的油 从而减小花费

那么选择所有比初始S贵的里面最便宜G的  那么从S到G花费起点S的油钱 从G到终点E 再化一部分新加的G站油钱 如果不是这样选 得到的花费只会更大 怎么呢?

我们来看 这种情况下 续命油的油量是确定的 因为我前面加满了 

如果选择一个更近的站A但并不是可选加油站中最便宜的 那么从起点S到A花费不变,从A到G花费不变 但到终点需要加一次油 这时需要加的油会更贵一点(A站油钱) 从而全局花费更大

如果选择一个更远的站B但并不是可选加油站中最便宜的 那么起点到G花费不变 G到B花费不变 B到终点E 需要续一次油 花费变大(B站油钱)

所以在这种 分支下 我们也要选择贵中最便宜的那个去加油 从而获得全局最优

我们要找的续命的加油站 必须是可达范围里最便宜的 只有这样 才能通过这个最便宜的加油站 获取尽可能便宜的局部最优花费 这样再去选 

你有可能会有疑问

如果我们想G走着走着发现一个可达范围内更便宜站P的怎么办 即便如此 我们也要先到G站 看看能不能不加油直接走到P站 不过不可能! 因为P是G站决策之前的可达范围之外的站 必然不可能不加油走到P站 所以我们有必要中间续油 那么续油的话 只能在G续油 因为G是最相对便宜的 我们只有先到了G再看看需要续多少油到更便宜的加油站去 如果没有更便宜的加油站 则继续选择可达范围内所有更贵的里面最便宜的  所以整个过程就是

局部最优+局部最优+...+局部最优 = 全局最优

 

于是这个问题的逻辑大致就是如此 对每个加油站执行相同的逻辑 我们发现这样的话就是贪心策略 每到一个加油站 在能到达的范围内选择局部最优策略 这样走下来就能得到全局最优策略 如果在加油站不进行局部最优的策略 那么就必然导致花费变大

如果起始点没有加油站 那么就输出0 因为加不到油必然走不出去

否则:

看看加满油的话 能到达的范围内 有没有加油站 

                     如果没有 那么就加满油尽可能跑 能跑多远就输出多远

                     如果有加油站 看看有没有一个加油站是他能到达的范围内且离当前点比较近的?我们设此站位G站

                                 如果有 我们就买刚好到G站的油量:因为到了G站买油可以得到更便宜的价格 从而尽可能的得到更小的花费                                 如果没有 全都是比当前站更贵的加油站 那么就要从贵中选一个最便宜的设为H站 我们要走到那里继续买油才能尽可能的减小花费 注意 这时要从当前站加满油 因为H站的油是更贵的 但是又不能因为油贵而不走 还是要尽可能往前走的 这时如果不从H站买 从其他站买 只会导致更多的花费  所以我们要尽可能少的从H站买油 我们到了H站要站在H站的位置考虑更优的花费时 再从H站买油 故从当前站要加满油 然后去向H站   

 

由于本题需要维护的参数比较多 逻辑比较复杂 还是要想清楚逻辑后 把变量写的可读性高点 才能少出bug

时间复杂度:O(n^(所能到达的范围中的加油站个数))<O(n^2)<1000ms

 

#include<cstdio>
#include<cstring>
#include<iostream>
#include<map>
#include<cmath>
#include<algorithm>
#include<set>
#include<vector>
#include<climits>
#define Equal(a,b) (fabs((a)-(b))<=eps)
#define LessEqu(a,b) (((a)-(b))<=eps)
#define Lessthan(a,b) (((a)-(b))<-eps)
#define Morethan(a,b) (((a)-(b))>=eps)
#define MoreEqu(a,b) (((a)-(b))>=-eps)
const double eps = 1e-5;
using namespace std;
typedef long long ll;
struct station{
    double cost;
    double dis;
}S[510];
bool cmp(station a,station b){
    return Lessthan(a.dis,b.dis);
}
int main(){
    double c,dis,avg;
    int sta;
    ios::sync_with_stdio(0);

    cin>>c>>dis>>avg>>sta;
    for(int i=1;i<=sta;i++){
        cin>>S[i].cost>>S[i].dis;
    }
    double Lowest = S[1].cost;

    for(int i=2;i<=sta;i++){
        if(Lessthan(S[i].cost,Lowest)){
            Lowest = S[i].cost;
        }
    }

    sort(S+1,S+1+sta,cmp);
    if(!Equal(S[1].dis,0.0)){
        cout<<"The maximum travel distance = 0.00"<<endl;
        return 0;
    }

    bool f=0;
    S[sta+1].cost = 0,S[sta+1].dis = dis;
    double exp=0,canadd=c,distans=0,cut=0,unit=c;
   
    double costoil,oil = 0;
    bool fal = 0;
    for(int i=1;i<sta+1;i++){
        oil = (distans-S[i].dis)/avg;
        double Maxlim = S[i].dis + c*avg;
        double CMP = S[i].cost;
        int j,u=i;
        for(j=i+1;j<=sta+1&&LessEqu(S[j].dis,Maxlim);j++){
            if(Lessthan(S[j].cost,CMP)){
                CMP = S[j].cost;
                u = j;
                break;
            }
        }
        if(u==i&&j==i+1){//后面没加油站
            distans = Maxlim;
            fal = 1;
            break;
        }
        if(u!=i){//有个更便宜的
            unit = (S[u].dis-distans)/avg;//减去的是什么很关键
            exp+=S[i].cost*unit;
           // canadd = unit;
            distans = S[u].dis;
            i = u-1;
            oil += unit;
            costoil = unit;
            continue;
        }
        //如果后面的都是比自己贵的
        CMP = S[i+1].cost;
        u = i+1;
        for(int j=i+2;j<=sta+1&&LessEqu(S[j].dis,Maxlim);j++){
            if(LessEqu(S[j].cost,CMP)){//尽可能少买 也就是尽可能远
                CMP = S[j].cost;
                u = j;
            }
        }
        canadd = c-oil;
        distans += (canadd)*avg;
         exp+=canadd*S[i].cost;
        costoil = (S[u].dis-S[i].dis)/avg;
        oil=c;
        i = u-1;
    }


    if(fal)printf("The maximum travel distance = %.2f\n",distans);
    else printf("%.2f\n",round(exp*100)/100);
    return 0;
}

 

标题SpringBoot智能在线预约挂号系统研究AI更换标题第1章引言介绍智能在线预约挂号系统的研究背景、意义、国内外研究现状及论文创新点。1.1研究背景与意义阐述智能在线预约挂号系统对提升医疗服务效率的重要性。1.2国内外研究现状分析国内外智能在线预约挂号系统的研究与应用情况。1.3研究方法及创新点概述本文采用的技术路线、研究方法及主要创新点。第2章相关理论总结智能在线预约挂号系统相关理论,包括系统架构、开发技术等。2.1系统架构设计理论介绍系统架构设计的基本原则和常用方法。2.2SpringBoot开发框架理论阐述SpringBoot框架的特点、优势及其在系统开发中的应用。2.3数据库设计与管理理论介绍数据库设计原则、数据模型及数据库管理系统。2.4网络安全与数据保护理论讨论网络安全威胁、数据保护技术及其在系统中的应用。第3章SpringBoot智能在线预约挂号系统设计详细介绍系统的设计方案,包括功能模块划分、数据库设计等。3.1系统功能模块设计划分系统功能模块,如用户管理、挂号管理、医生排班等。3.2数据库设计与实现设计数据库表结构,确定字段类型、主键及外键关系。3.3用户界面设计设计用户友好的界面,提升用户体验。3.4系统安全设计阐述系统安全策略,包括用户认证、数据加密等。第4章系统实现与测试介绍系统的实现过程,包括编码、测试及优化等。4.1系统编码实现采用SpringBoot框架进行系统编码实现。4.2系统测试方法介绍系统测试的方法、步骤及测试用例设计。4.3系统性能测试与分析对系统进行性能测试,分析测试结果并提出优化建议。4.4系统优化与改进根据测试结果对系统进行优化和改进,提升系统性能。第5章研究结果呈现系统实现后的效果,包括功能实现、性能提升等。5.1系统功能实现效果展示系统各功能模块的实现效果,如挂号成功界面等。5.2系统性能提升效果对比优化前后的系统性能
在金融行业中,对信用风险的判断是核心环节之一,其结果对机构的信贷政策和风险控制策略有直接影响。本文将围绕如何借助机器学习方法,尤其是Sklearn工具包,建立用于判断信用状况的预测系统。文中将涵盖逻辑回归、支持向量机等常见方法,并通过实际操作流程进行说明。 一、机器学习基本概念 机器学习属于人工智能的子领域,其基本理念是通过数据自动学习规律,而非依赖人工设定规则。在信贷分析中,该技术可用于挖掘历史数据中的潜在规律,进而对未来的信用表现进行预测。 二、Sklearn工具包概述 Sklearn(Scikit-learn)是Python语言中广泛使用的机器学习模块,提供多种数据处理和建模功能。它简化了数据清洗、特征提取、模型构建、验证与优化等流程,是数据科学项目中的常用工具。 三、逻辑回归模型 逻辑回归是一种常用于分类任务的线性模型,特别适用于二类问题。在信用评估中,该模型可用于判断借款人是否可能违约。其通过逻辑函数将输出映射为0到1之间的概率值,从而表示违约的可能性。 四、支持向量机模型 支持向量机是一种用于监督学习的算法,适用于数据维度高、样本量小的情况。在信用分析中,该方法能够通过寻找最佳分割面,区分违约与非违约客户。通过选用不同核函数,可应对复杂的非线性关系,提升预测精度。 五、数据预处理步骤 在建模前,需对原始数据进行清理与转换,包括处理缺失值、识别异常点、标准化数值、筛选有效特征等。对于信用评分,常见的输入变量包括收入水平、负债比例、信用历史记录、职业稳定性等。预处理有助于减少噪声干扰,增强模型的适应性。 六、模型构建与验证 借助Sklearn,可以将数据集划分为训练集和测试集,并通过交叉验证调整参数以提升模型性能。常用评估指标包括准确率、召回率、F1值以及AUC-ROC曲线。在处理不平衡数据时,更应关注模型的召回率与特异性。 七、集成学习方法 为提升模型预测能力,可采用集成策略,如结合多个模型的预测结果。这有助于降低单一模型的偏差与方差,增强整体预测的稳定性与准确性。 综上,基于机器学习的信用评估系统可通过Sklearn中的多种算法,结合合理的数据处理与模型优化,实现对借款人信用状况的精准判断。在实际应用中,需持续调整模型以适应市场变化,保障预测结果的长期有效性。 资源来源于网络分享,仅用于学习交流使用,请勿用于商业,如有侵权请联系我删除!
### NetCDF 文件中数据类型无效或 _FillValue 类型不匹配解决方案 当处理 NetCDF 文件时,如果遇到数据类型无效或 `_FillValue` 类型不匹配的问题,通常是因为定义的数据类型与实际存储的数据类型不符。为了确保一致性并解决问题,可以采取以下措施: #### 验证和调整数据类型 在创建或修改 NetCDF 文件时,务必确认变量声明的数据类型与其对应的 `_FillValue` 的数据类型一致。例如,在 Java 中使用 `netCDF` 库时,可以通过如下方式设置合适的约束条件来验证特征类型的合法性[^1]。 ```java // 创建一个新的特征类型约束对象用于检查有效性 FeatureTypeConstraint constraint = styleFactory.createFeatureTypeConstraint("Feature", Filter.INCLUDE, null); ``` 对于具体的数据类型校验,则应通过编程接口获取当前使用的填充值及其所属类型,并将其转换为目标类型后再赋给相应属性。下面是一个 Python 示例代码片段展示如何操作 netCDF4 模块中的文件以修正此类错误: ```python import numpy as np from netCDF4 import Dataset def fix_fillvalue_type(ncfile_path): with Dataset(ncfile_path, 'r+') as ds: for var_name in ds.variables.keys(): variable = ds[var_name] # 获取原始 FillValue 和 dtype 属性 fill_value = getattr(variable, '_FillValue', None) if isinstance(fill_value, (np.floating)): new_dtype = float elif isinstance(fill_value, (int, np.integer)): new_dtype = int else: continue # 如果现有 dtype 不同于推断的新 dtype 则更新它 current_dtype = variable.dtype.type if not issubclass(current_dtype, new_dtype): print(f'Changing {var_name} from type {current_dtype.__name__} to {new_dtype.__name__}') # 更新变量的 dtype 并重新设定 FillValue delattr(variable, "_FillValue") # 删除旧的 FillValue 属性 variable.setncattr("_FillValue", np.array([fill_value], dtype=new_dtype)[0]) ``` 此函数遍历指定路径下的 NetCDF 文件内的所有变量,针对每个变量判断其 `_FillValue` 是否存在以及是否需要更改关联的数据类型;一旦发现差异即执行必要的更正动作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值