(M)Dynamic Programming:309. Best Time to Buy and Sell Stock with Cooldown

本文介绍了一种使用动态规划解决股票买卖问题的方法,旨在找到最佳买卖时机以获得最大利润。通过定义持股(buy)和未持股(sell)两种状态,利用状态转移方程实现了算法设计。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

此题不会。看大神的分析:

对于这一天是否持股只有两种状态:持股状态(buy),没有持股状态(sell,cooldown)。
对于当天持股状态时,至当天的为止的最大利润有两种可能:1、今天没有买入,跟昨天持股状态一样;2、今天买入,昨天是冷却期,利润是前天卖出股票时候得到的利润减去今天股票的价钱。 二者取最大值。
对于当天未持股状态,至当天为止的最大利润有两种可能:1、今天没有卖出,跟昨天未持股状态一样;2、昨天持有股票,今天卖出了,利润是昨天持有股票时候的利润加上今天股票的价钱。 二者取最大值。
直至最后一天的状态应该是卖出状态。最终利润为sell[n-1];
状态转移方程:
sell[i] = max(sell[i-1], buy[i-1] + price[i]);
buy[i] = max(buy[i-1], sell[i-2] - price[i]);

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        int buy(INT_MIN), sell(0), prev_sell(0), prev_buy;
        for (int price : prices) {
            prev_buy = buy;
            buy = max(prev_sell - price, buy);
            prev_sell = sell;
            sell = max(prev_buy + price, sell);
        }
        return sell;
    }
};


修改代码,使# 处理01-07的情况部分的代码# 保存并上传图片立即# 进入3秒冷却状态,防止重复上传和同时发送前进命令。输出完整代码 import logging from maix import camera, display, image, nn, app, uart, time import requests import json import os import threading from datetime import datetime # 日志配置 logging.basicConfig( level=logging.INFO, format='%(asctime)s [%(levelname)s] %(message)s', handlers=[ logging.FileHandler("/root/operation.log"), logging.StreamHandler() ] ) logger = logging.getLogger("MAIX_PRO") # 状态定义 class SystemState: NORMAL = 0 # 正常检测模式 OBJECT_DETECTED = 1 # 物体检测处理中 SPECIAL_HANDLING = 2 # 特殊处理模式(标签08) WAIT_FOR_LABEL1 = 3 # 等待标签1状态 UPLOADING = 4 # 上传处理中状态 PAUSED = 5 # 暂停状态,等待UART信号 COOLDOWN = 6 # 新增:冷却状态,防止重复上传 # OCR模型加载 try: ocr = nn.PP_OCR(model="/root/models/pp_ocr.mud") logger.info("OCR model loaded") except Exception as e: logger.critical(f"OCR model load failed: {str(e)}") exit(1) # 保存目录 SAVE_DIR = "/boot/Pictures/" os.makedirs(SAVE_DIR, exist_ok=True) # 更新ROI区域定义 (x, y, w, h) - 使用新参数 (138, 139, 44, 85) ROI_X = 138 ROI_Y = 139 ROI_W = 44 ROI_H = 85 # 硬件初始化(使用OCR模型要求的分辨率) try: cam = camera.Camera(ocr.input_width(), ocr.input_height(), ocr.input_format()) logger.debug(f"Camera resolution: {cam.width()}x{cam.height()}") except RuntimeError as e: logger.critical(f"Camera init failed: {str(e)}") exit(1) disp = display.Display() # UART初始化 device = "/dev/ttyS0" serial0 = uart.UART(device, 115200) logger.info("UART initialized") # 使用固定token替换登录流程 token = "eyJhbGciOiJIUzI1NiJ9.eyJpZCI6MTkwNTgwNDA0MTExNjU2OTYwMSwidXNlclJvbGUiOiJhZG1pbiIsImV4cCI6ODY0MTc1MjM3MDQzNiwidXNlcm5hbWUiOm51bGx9.3TxID4LJExTSDFxo4jr8LuIgFYgO2cSp7Z3sqPATVc0" logger.info(f"Using fixed token: {token[:10]}...") # 只打印前10位避免日志过长 class OperationController: def __init__(self): self.state = SystemState.NORMAL self.current_label = None self.last_detect_time = 0 self.upload_complete = False self.lock = threading.Lock() self.timers = [] # 初始发送forward命令 (0x02) self.send_uart("right") # 初始化 photo_url 及 data_url self.photo_url = "http://111.230.114.23/api/file/upload" self.data_url = "http://111.230.114.23/api/data/add" # 使用固定token self.token = token # 启动UART接收线程 self.uart_receive_thread = threading.Thread(target=self.uart_receive_loop, daemon=True) self.uart_receive_thread.start() logger.info("UART receive thread started") def uart_receive_loop(self): """UART接收线程,处理接收到的数据""" while True: try: # 读取UART数据 data = serial0.read(1) # 每次读取一个字节 if data is not None and len(data) > 0: # 将字节转换为整数 byte_val = data[0] logger.info(f"UART received byte: {hex(byte_val)}") if byte_val == 0x02: # 收到0x02时重置状态为NORMAL with self.lock: logger.info("Received 0x02, reset state to NORMAL") self.state = SystemState.NORMAL # 发送前进命令 self.send_uart("right") except Exception as e: logger.error(f"UART receive error: {str(e)}") time.sleep_ms(10) # 避免过度占用CPU def send_uart(self, command): """发送带十六进制前缀的UART命令,命令为单字节""" # 如果当前处于上传状态,则不发送任何UART命令 if self.state == SystemState.UPLOADING: logger.warning(f"Blocked UART command during upload: {command}") return try: # 命令映射表 command_map = { "stop": 0x00, # 停止命令 "left": 0x01, # 左转命令 "right": 0x02 # 右转/前进命令 } # 获取命令对应的字节值 if command in command_map: cmd_byte = bytes([command_map[command]]) else: logger.error(f"Unknown command: {command}") return # 创建十六进制前缀字节序列 header = bytes.fromhex('ffff02') # 组合所有部分:header + cmd_byte data_to_send = header + cmd_byte # 发送完整的字节序列 serial0.write(data_to_send) logger.info(f"UART sent: {data_to_send.hex()} (hex)") except Exception as e: logger.error(f"UART send failed: {str(e)}") def save_and_upload(self, img, label): try: # 设置上传状态,阻止UART发送 self.state = SystemState.UPLOADING logger.info(f"Starting upload for label {label} (UART blocked)") # 生成文件名 timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") filename = f"{SAVE_DIR}{label}_{timestamp}.jpg" # 保存图片 if img.save(filename, quality=90): logger.info(f"Image saved: {filename}") # 同步上传 with open(filename, 'rb') as file: files = { 'file': ('image.jpg', file, 'image/jpeg') } params = { 'biz': 'plant_picture', } headers = { "token": self.token } logger.info(f"Uploading {filename} with label {label}, Token: {self.token[:10]}...") response = requests.post( self.photo_url, files=files, headers=headers, params=params ) if response.json().get('code') == 0: logger.info(f"Upload success: {filename}, Response: {response.text}") return response.json().get('data') else: logger.warning(f"Upload failed: {response.text}") else: logger.error("Image save failed") except Exception as e: logger.error(f"Capture failed: {str(e)}") finally: # 恢复状态,允许UART发送 self.state = SystemState.NORMAL logger.info(f"Upload completed for label {label} (UART unblocked)") return None def save_data(self, data): try: # 设置上传状态,阻止UART发送 self.state = SystemState.UPLOADING logger.info("Starting data save (UART blocked)") params = [{ "deviceName": 1, "plantId": 1, "growthStage": "flowering", "healthStage": "healthy", "height": "5", "crownWidth": "5", "humidity": '', "ph": '', "dan": '', "lin": '', "jia": '', "photoUrl": data, "notes": "" }] headers = { "token": self.token } response = requests.post( self.data_url, headers=headers, json=params ) logger.info(f"Response: {data}") if response.json().get('code') == 0: logger.info(f"Data save success: {response.text}") else: logger.warning(f"Data save failed: {response.text}") except Exception as e: logger.error(f"Data upload error: {str(e)}") finally: # 恢复状态,允许UART发送 self.state = SystemState.NORMAL logger.info("Data save completed (UART unblocked)") def get_ocr_text(self, obj): """安全获取OCR文本内容""" try: # 尝试获取文本内容 text = obj.char_str # 如果char_str是方法则调用它 if callable(text): text = text() # 确保是字符串类型 return str(text).strip() except Exception as e: logger.error(f"获取OCR文本失败: {str(e)}") return "" def handle_detection(self, objs, img): with self.lock: current_time = time.time() # 状态机逻辑 if self.state == SystemState.NORMAL: for obj in objs: # 使用安全方法获取文本 text = self.get_ocr_text(obj) logger.info(f"OCR detected text: {text}") # 处理01-07的情况 if text in ["01", "02", "03", "04", "05", "06", "07"]: num = int(text) # 转换为整数 logger.info(f"Label {num} detected via OCR") self.state = SystemState.OBJECT_DETECTED self.send_uart("stop") # 发送停止命令 (0x00) # 1秒后保存并上传 def delayed_save(): # 保存并上传图片 data = self.save_and_upload(img, num) if data: self.save_data(data) # 上传完成后立即发送前进命令 self.send_uart("right") # 进入3秒冷却状态,防止重复上传 self.state = SystemState.COOLDOWN logger.info(f"Entering 3-second cooldown state for label {num}") # 3秒后重置状态为NORMAL def reset_state(): self.state = SystemState.NORMAL logger.info(f"Cooldown finished, state reset to NORMAL for label {num}") self.add_timer(3.0, reset_state) self.add_timer(1.0, delayed_save) break # 处理一个有效结果后退出循环 # 处理08的情况 elif text == "08": logger.info("Special label 08 detected") self.state = SystemState.SPECIAL_HANDLING self.send_uart("stop") # 发送停止命令 (0x00) # 1秒后保存并上传 def delayed_save(): data = self.save_and_upload(img, 8) if data: self.save_data(data) self.send_uart("left") # 发送左转命令 (0x01) # 进入等待标签1状态 self.state = SystemState.WAIT_FOR_LABEL1 self.add_timer(1.0, delayed_save) break # 处理一个有效结果后退出循环 elif self.state == SystemState.SPECIAL_HANDLING: # 等待上传完成 pass elif self.state == SystemState.WAIT_FOR_LABEL1: for obj in objs: text = self.get_ocr_text(obj) if text == "01": logger.info("Label1 after special handling") self.send_uart("stop") # 发送停止命令 (0x00) break def add_timer(self, delay, callback): timer = threading.Timer(delay, callback) timer.start() self.timers.append(timer) def cleanup(self): for timer in self.timers: timer.cancel() logger.info("System cleanup completed") # 主控制实例 controller = OperationController() # 创建颜色对象 red_color = image.Color(255, 0, 0) # 红色 - 用于检测框 green_color = image.Color(0, 255, 0) # 绿色 - 用于ROI框 blue_color = image.Color(0, 0, 255) # 蓝色 - 用于文本 yellow_color = image.Color(255, 255, 0) # 黄色 - 用于警告信息 # 主循环 try: # 帧率计算变量 frame_count = 0 last_log_time = time.time() while not app.need_exit(): try: # 读取图像 img = cam.read() frame_count += 1 except Exception as e: logger.error(f"摄像头读取失败: {str(e)}") continue # 绘制ROI区域边框 - 使用新的矩形参数 (138, 139, 44, 85) img.draw_rect(ROI_X, ROI_Y, ROI_W, ROI_H, green_color, thickness=2) # 添加ROI区域标签 img.draw_string(ROI_X, ROI_Y - 20, f"ROI: {ROI_X},{ROI_Y},{ROI_W},{ROI_H}", scale=0.7, color=blue_color) # 裁剪ROI区域 try: # 使用crop方法裁剪ROI区域 roi_img = img.crop(ROI_X, ROI_Y, ROI_W, ROI_H) except Exception as e: logger.error(f"ROI裁剪失败: {str(e)}") disp.show(img) continue # 执行OCR识别(仅在ROI区域) try: objs = ocr.detect(roi_img) except Exception as e: logger.error(f"OCR识别失败: {str(e)}") disp.show(img) continue # 调整检测框坐标(从ROI坐标转换到原始图像坐标) adjusted_objs = [] for obj in objs: # 直接修改原始对象坐标 obj.box.x1 += ROI_X obj.box.y1 += ROI_Y obj.box.x2 += ROI_X obj.box.y2 += ROI_Y obj.box.x3 += ROI_X obj.box.y3 += ROI_Y obj.box.x4 += ROI_X obj.box.y4 += ROI_Y adjusted_objs.append(obj) # 处理结果 if len(adjusted_objs) > 0: controller.handle_detection(adjusted_objs, img) # 显示OCR结果 for obj in adjusted_objs: # 绘制检测框(四个点) points = obj.box.to_list() img.draw_keypoints( points, red_color, # 颜色 4, # 点大小 -1, # 连接所有点 1 # 线宽 ) # 安全获取文本内容 try: text = controller.get_ocr_text(obj) # 绘制识别文本 img.draw_string( obj.box.x4, obj.box.y4, text, scale=0.5, color=red_color ) except Exception as e: logger.error(f"绘制OCR文本失败: {str(e)}") img.draw_string( obj.box.x4, obj.box.y4, "ERROR", scale=0.5, color=yellow_color ) # 显示状态信息 state_text = f"State: {controller.state}" img.draw_string(5, 5, state_text, scale=0.8, color=blue_color) # 显示检测结果数量 count_text = f"Detected: {len(adjusted_objs)}" img.draw_string(5, 25, count_text, scale=0.8, color=blue_color) # 显示当前时间 time_text = datetime.now().strftime("%H:%M:%S") img.draw_string(img.width() - 100, 5, time_text, scale=0.8, color=blue_color) # 显示帧率 if time.time() - last_log_time > 1.0: fps = frame_count img.draw_string(5, 45, f"FPS: {fps}", scale=0.8, color=blue_color) frame_count = 0 last_log_time = time.time() # 显示图像 disp.show(img) except KeyboardInterrupt: logger.info("用户中断") except Exception as e: logger.critical(f"致命错误: {str(e)}") finally: controller.cleanup() logger.info("系统关闭")
最新发布
07-14
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值