换教室(动态规划+floyed)

终于ac了,,好开心啊,,

这道题我第一眼看到时头很大,因为题干很长,不过类型很好判断

概率dp+最短路

首先floyed求出两两间的最短路,记为d[i][j]

f[i][j][1/0]表示在第i个时间段,申请了j个教室,1表示通过,

0表示不通过

a[i]表示原来时间段的教室,b[i]表示更换后的教室,c[i]表示申请成功的概率

转移状态时,当前时间段是由上一个时间段申请转移和不申请转移

申请又分为申请通过和不通过

于是就有了状态转移方程:

f[i][j][0] = min(f[i-1][j][0] + d[a[i-1]][a[i]], f[i-1][j][1] + d[a[i-1]][a[i]] (1 - c[i-1]) + d[b[i-1]][a[i]] c[i-1]);

f[i][j][1] = min(f[i-1][j-1][0] + d[a[i-1]][a[i]] (1.0-c[i]) + d[a[i-1]][b[i]] c[i], f[i-1][j-1][1] + d[a[i-1]][a[i]] (1.0-c[i-1]) (1.0-c[i]) + d[b[i-1]][a[i]] c[i-1] (1.0-c[i]) + d[a[i-1]][b[i]] (1.0-c[i-1]) c[i] + d[b[i-1]][b[i]] c[i-1] c[i]);

附上代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=2018,maxm=310;
int a[maxn],b[maxn];
double d[maxm][maxm],c[maxn],f[maxn][maxn][2];
int cnt=0;
int n,m,v,e;
void init()
{
    for(int i=0;i<maxm;i++)
        for(int j=0;j<maxm;j++)
            if(i==j)d[i][j]=0;
            else d[i][j]=1e9;
    for (int i=0;i<maxn;i++)
        for (int j=0;j<maxn;j++)
            f[i][j][0]=f[i][j][1]=1e9;
    f[1][0][0]=0;f[1][1][1]=0;
}
int main()
{
    scanf("%d%d%d%d",&n,&m,&v,&e);
    for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    for(int i=1;i<=n;i++)scanf("%d",&b[i]);
    for(int i=1;i<=n;i++)scanf("%lf",&c[i]);
    init();
    for(int i=1;i<=e;i++)
    {
        int x,y,z;
        scanf("%d%d%d",&x,&y,&z);
        if(x==y)continue;
        if(z<d[x][y])d[x][y]=z;
        d[y][x]=d[x][y];
    }
    for(int k=1;k<=v;k++)
       for(int i=1;i<=v;i++)
          for(int j=1;j<=v;j++)
             if(d[i][k]+d[k][j]<d[i][j])
                d[i][j]=d[i][k]+d[k][j];
    for(int i=2;i<=n;i++)
    {
        f[i][0][0]=f[i-1][0][0]+d[a[i-1]][a[i]];
        for(int j=1;j<=min(m,i);j++)
        {
            f[i][j][0]=min(f[i-1][j][0]+d[a[i-1]][a[i]],f[i-1][j][1]+d[a[i-1]][a[i]]*(1.0-c[i-1])+d[b[i-1]][a[i]]*c[i-1]);
            f[i][j][1]=f[i-1][j-1][0]+d[a[i-1]][a[i]]*(1.0-c[i])+d[a[i-1]][b[i]]*c[i];
            double t=f[i-1][j-1][1]+d[a[i-1]][a[i]]*(1.0-c[i-1])*(1.0-c[i]);
            t+=d[b[i-1]][a[i]]*c[i-1]*(1.0-c[i]);
            t+=d[a[i-1]][b[i]]*(1.0-c[i-1])*c[i];
            t+=d[b[i-1]][b[i]]*c[i-1]*c[i];
            f[i][j][1]=min(f[i][j][1],t);
        } 
    }
    double ans=f[n][0][0];
    for(int i=1;i<=m;i++)
    {
        ans=min(ans,min(f[n][i][0],f[n][i][1]));
    }
    printf("%.2lf",ans);
    return 0;
} 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1 目标检测的定义 目标检测(Object Detection)的任务是找出图像中所有感兴趣的目标(物体),确定它们的类别和位置,是计算机视觉领域的核心问题之一。由于各类物体有不同的外观、形状和姿态,加上成像时光照、遮挡等因素的干扰,目标检测一直是计算机视觉领域最具有挑战性的问题。 目标检测任务可分为两个关键的子任务,目标定位和目标分类。首先检测图像中目标的位置(目标定位),然后给出每个目标的具体类别(目标分类)。输出结果是一个边界框(称为Bounding-box,一般形式为(x1,y1,x2,y2),表示框的左上角坐标和右下角坐标),一个置信度分数(Confidence Score),表示边界框中是否包含检测对象的概率和各个类别的概率(首先得到类别概率,经过Softmax可得到类别标签)。 1.1 Two stage方法 目前主流的基于深度学习的目标检测算法主要分为两类:Two stage和One stage。Two stage方法将目标检测过程分为两个阶段。第一个阶段是 Region Proposal 生成阶段,主要用于生成潜在的目标候选框(Bounding-box proposals)。这个阶段通常使用卷积神经网络(CNN)从输入图像中提取特征,然后通过一些技巧(如选择性搜索)来生成候选框。第二个阶段是分类和位置精修阶段,将第一个阶段生成的候选框输入到另一个 CNN 中进行分类,并根据分类结果对候选框的位置进行微调。Two stage 方法的优点是准确度较高,缺点是速度相对较慢。 常见Tow stage目标检测算法有:R-CNN系列、SPPNet等。 1.2 One stage方法 One stage方法直接利用模型提取特征值,并利用这些特征值进行目标的分类和定位,不需要生成Region Proposal。这种方法的优点是速度快,因为省略了Region Proposal生成的过程。One stage方法的缺点是准确度相对较低,因为它没有对潜在的目标进行预先筛选。 常见的One stage目标检测算法有:YOLO系列、SSD系列和RetinaNet等。 2 常见名词解释 2.1 NMS(Non-Maximum Suppression) 目标检测模型一般会给出目标的多个预测边界框,对成百上千的预测边界框都进行调整肯定是不可行的,需要对这些结果先进行一个大体的挑选。NMS称为非极大值抑制,作用是从众多预测边界框中挑选出最具代表性的结果,这样可以加快算法效率,其主要流程如下: 设定一个置信度分数阈值,将置信度分数小于阈值的直接过滤掉 将剩下框的置信度分数从大到小排序,选中值最大的框 遍历其余的框,如果和当前框的重叠面积(IOU)大于设定的阈值(一般为0.7),就将框删除(超过设定阈值,认为两个框的里面的物体属于同一个类别) 从未处理的框中继续选一个置信度分数最大的,重复上述过程,直至所有框处理完毕 2.2 IoU(Intersection over Union) 定义了两个边界框的重叠度,当预测边界框和真实边界框差异很小时,或重叠度很大时,表示模型产生的预测边界框很准确。边界框A、B的IOU计算公式为: 2.3 mAP(mean Average Precision) mAP即均值平均精度,是评估目标检测模型效果的最重要指标,这个值介于0到1之间,且越大越好。mAP是AP(Average Precision)的平均值,那么首先需要了解AP的概念。想要了解AP的概念,还要首先了解目标检测中Precision和Recall的概念。 首先我们设置置信度阈值(Confidence Threshold)和IoU阈值(一般设置为0.5,也会衡量0.75以及0.9的mAP值): 当一个预测边界框被认为是True Positive(TP)时,需要同时满足下面三个条件: Confidence Score > Confidence Threshold 预测类别匹配真实值(Ground truth)的类别 预测边界框的IoU大于设定的IoU阈值 不满足条件2或条件3,则认为是False Positive(FP)。当对应同一个真值有多个预测结果时,只有最高置信度分数的预测结果被认为是True Positive,其余被认为是False Positive。 Precision和Recall的概念如下图所示: Precision表示TP与预测边界框数量的比值 Recall表示TP与真实边界框数量的比值 改变不同的置信度阈值,可以获得多组Precision和Recall,Recall放X轴,Precision放Y轴,可以画出一个Precision-Recall曲线,简称P-R
动态规划是一种算法设计技术,通常用于解决最优化问题,特别适用于那些有重叠子问题和最优子结构特征的问题。以下是关于动态规划的一些关键点,大约1000字的笔记概要: 1. **基础概念**: - 它将复杂问题分解成更小的子问题,并存储解决方案,避免重复计算。 - 遵循“自底向上”(bottom-up)或“贪心策略”的原则。 2. **核心思想**: - 最优子结构:问题的最优解可以由其子问题的最优解组成。 - 无后效性:一旦做出某个决策,就不会影响先前已经做出的其他决策的最优值。 3. **基本步骤**: a. 状态定义:明确问题的状态变量,通常是通过前一阶段的决策组合得到的。 b. 状态转移方程:描述如何从当前状态转到下一个状态并求解目标函数。 c. 边界条件:确定初始状态或最简单情况下的状态值。 d. 更新表:按照顺序填充状态值表格,最终结果在最复杂的状态下找到。 4. **典型应用**: - 背包问题(0-1背包、完全背包、多重背包) - 最长公共子序列(LCS) - 最短路径(Dijkstra, Floyed-Warshall算法) - 最大子数组(Kadane's Algorithm) - 编辑距离 5. **注意事项**: - 避免重复工作:动态规划的关键在于记住之前的结果,避免不必要的计算。 - 计算空间管理:内存消耗较大,需要谨慎设计存储结构。 6. **案例分析**: 分析一个具体的例子,如斐波那契数列,说明如何将其转化为动态规划问题,并写出伪代码和Python实现。 7. **总结和拓展**: - 动态规划与其他算法的区别(例如分治法、贪心等)。 - 动态规划在实际项目中的应用场景和优化策略。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值