当前位置: 首页 > article >正文

蓝桥杯每日真题 - 第19天

题目:(费用报销)

题目描述(13届 C&C++ B组F题)

 

解题思路:

1. 问题抽象

本问题可以看作一个限制条件较多的优化问题,核心是如何在金额和时间约束下选择最优方案

  • 动态规划是理想的解决方法。

  • 我们定义 dp[i]到第 i 天为止的最大报销金额

2. 日期统一化

为了方便处理时间差,需将日期(月份和天数)统一转化为一年中的第几天。例如:

  • 1 月 1 日为第 1 天;

  • 2 月 1 日为第 32 天(31+1)。

这一步能让日期差的计算简单且高效。

3. 动态规划状态转移

  • 状态表示dp[i] 表示到第 i 天为止的最大报销金额。

  • 转移方程:对每张票据:

    • 如果报销当前票据:dp[i] = max(dp[i-1], dp[pre] + v[i]),其中 pre = i - K

    • 如果不报销当前票据:dp[i] = dp[i-1]

4. 优化思路

  • 按票据日期排序,确保动态规划时的时间顺序正确。

  • 动态更新 dp 数组,逐步累积最大金额。

代码实现(C语言):

#include <stdio.h>
#include <stdlib.h>

typedef struct {
  int day, v;
} dps;

int N, M, K;
int m[1009], d[1009];
dps dp[1009];
int a[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int p[366] = {0};

// 计算每月对应的天数累计和
int month(int mi) {
  int sum = 0;
  for (int i = 0; i < mi - 1; i++) sum += a[i];
  return sum;
}

// 将日期统一成一年中的第几天
void becomeday() {
  for (int i = 0; i < N; i++) {
    dp[i].day = month(m[i]) + d[i];
    p[dp[i].day] = dp[i].v;
  }
}

// 比较函数,用于qsort排序
int cmp(const void *a1, const void *a2) {
  dps s1 = *(dps *)a1;
  dps s2 = *(dps *)a2;
  return s1.day - s2.day;
}

int main() {
  scanf("%d%d%d", &N, &M, &K);
  for (int i = 0; i < N; i++) {
    scanf("%d%d%d", &m[i], &d[i], &dp[i].v);
  }
  
  // 转换日期并排序
  becomeday();
  qsort(dp, N, sizeof(dp[0]), cmp);
  
  // 动态规划
  for (int i = 1; i < 366; i++) {
    int pre = i - K >= 0 ? i - K : 0;
    if (p[i] + p[pre] <= M) {
      p[i] = p[i] + p[pre] > p[i - 1] ? p[i] + p[pre] : p[i - 1];
    } else {
      p[i] = p[i - 1];
    }
  }
  
  printf("%d", p[365]);
  return 0;
}

得到运行结果:

难度分析

⭐️⭐️⭐️⭐️⭐️难难难难难难

总结

本题核心在于将日期处理动态规划相结合,解决了多条件限制下的最优选择问题。
以下是总结要点:

  1. 日期统一化:通过天数累计简化日期差值计算。

  2. 动态规划核心:记录每一天的最大报销金额,并逐步更新。

  3. 代码结构清晰:日期处理、排序和动态规划分模块实现,方便理解和维护。


http://www.kler.cn/a/405135.html

相关文章:

  • 构建无障碍的数字世界:深入探讨Web可访问性指南
  • 23种设计模式速记法
  • java: spire.pdf.free 9.12.3 create pdf
  • C++-第25课-哈希表性能的分析
  • [Unity]TileMap开发,TileMap地图缝隙问题
  • 网络安全之信息收集-实战-1
  • 第27天 安全开发-PHP应用TP 框架路由访问对象操作内置过滤绕过核心漏洞
  • 生产环境centos8 Red Hat8部署ansible and 一键部署mysql两主两从ansible脚本预告
  • 经验笔记:远端仓库和本地仓库之间的连接(以Gitee为例)
  • 在Sui 区块链上创建、部署和管理 NFT 的完整教程
  • java 设计模式 模板方法模式
  • shell脚本-笔记25
  • leetcode105:从前序与中序遍历构建二叉树
  • Java API 学习指南:从入门到精通的全面指导
  • 2.13 转换矩阵
  • 【数据库知识】mysql进阶-Mysql数据库的主从复制
  • Spring Boot核心概念:日志管理
  • SAP FICO 资产会计AA后台配置 (上)
  • PHP顺序查找和二分查找(也叫做折半查找)算法
  • Block Successive Upper Bound Minimization Method(BSUM)算法
  • Android 使用 LiveData/OnCheckedChangeListener 来监听变量变化
  • C++ 并发专题 - 线程安全的单例模式
  • Apache Maven简介
  • 给机器装上“脑子”—— 一文带你玩转机器学习
  • 博导的角度看,EtherNet/IP转Profinet网关的技术实现和区别
  • 基于Java Springboot社区便民服务管理系统