NOIp 2016 选课 (DP)

本文介绍了一个关于期望DP的经典问题及其解决方案。通过定义状态转移方程,利用动态规划求解最小期望值,适用于训练和理解期望DP的概念。

Problem

题目太长不复制粘贴了

Solution

经典的期望DP, 当作训练吧。

\(dp[i][j][0 / 1]\)表示前\(i\)门课使用\(j\)次申请换课机会, 本次选(\(1\))/不选(\(0\))体力消耗的最小期望值。

其他都写在注释里了。

#include <algorithm>
#include <cstdio>
#include <cstring>
int n, m, v, e;
int c[2010], d[2010];
double k[2010];
double adj[310][310];
double dp[2010][2010][2], ans(999999999.999999);
int main(int argc, char const *argv[]) {
  // Input
  scanf("%d %d %d %d", &n, &m, &v, &e);
  for (register int i(1); i <= n; ++i) {
    scanf("%d", &c[i]);
  }
  for (register int i(1); i <= n; ++i) {
    scanf("%d", &d[i]);
  }
  for (register int i(1); i <= n; ++i) {
    scanf("%lf", &k[i]);
  }
  memset(adj, 0x43, sizeof(adj));
  {
    register double c;
    for (register int i(1), a, b; i <= e; ++i) {
      scanf("%d %d %lf", &a, &b, &c);
      adj[a][b] = adj[b][a] = std::min(adj[a][b], c);
    }
  }
  // Run Floyd-Warshall algorithm to get the lengths of shortest paths between
  // each pair of classrooms.
  for (register int k(1); k <= v; ++k) {
    adj[k][k] = adj[k][0] = adj[0][k] = 0;
    for (register int i(1); i <= v; ++i) {
      for (register int j(1); j <= v; ++j) {
        adj[i][j] = adj[j][i] = std::min(adj[i][j], adj[i][k] + adj[k][j]);
      }
    }
  }
  // Run Dynamic programming to get the answer.
  memset(dp, 0x43, sizeof(dp));
  dp[1][0][0] = dp[1][1][1] = 0.000000;
  for (register int i(2); i <= n; ++i) {
    for (register int j(0); j <= m && j <= i; ++j) {
      // Not apply this time
      dp[i][j][0] = std::min(
          // Didn't apply for exchange before the previous class
          dp[i - 1][j][0] + adj[c[i - 1]][c[i]],
          // Applied last time
          dp[i - 1][j][1] +
              // Failed last time
              (1.000000 - k[i - 1]) * adj[c[i - 1]][c[i]] +
              // Succeeded last time
              k[i - 1] * adj[d[i - 1]][c[i]]);
      // Apply this time
      if (j >= 1) {
        dp[i][j][1] = std::min(
            // Didn't apply for exchange before the previous class
            dp[i - 1][j - 1][0] +
                // Failed this time
                (1.000000 - k[i]) * adj[c[i - 1]][c[i]] +
                // Succeeded this time
                k[i] * adj[c[i - 1]][d[i]],
            // Applied last time
            dp[i - 1][j - 1][1] +
                // Failed both last and this time
                (1.000000 - k[i - 1]) * (1.000000 - k[i]) *
                    adj[c[i - 1]][c[i]] +
                // Succeeded last time and failed this time
                k[i - 1] * (1.000000 - k[i]) * adj[d[i - 1]][c[i]] +
                // Failed last time and succeeded this time
                (1.000000 - k[i - 1]) * k[i] * adj[c[i - 1]][d[i]] +
                // Succeeded both last and this time
                k[i - 1] * k[i] * adj[d[i - 1]][d[i]]);
      }
    }
  }
  for (register int i(0); i <= m; ++i) {
    ans = std::min(ans, std::min(dp[n][i][0], dp[n][i][1]));
  // Output
  printf("%.2lf\n", ans);
  return 0;
}

转载于:https://www.cnblogs.com/forth/p/9910132.html

内容概要:本文围绕可变桨叶四旋翼无人机的规范控制与点对点运动模拟展开,重点研究优化推力分配策略在翻转动作中的应用与性能比较。通过Matlab代码实现,构建了四旋翼动力学模型,并设计了多种控制算法以实现精确的姿态调整与轨迹跟踪。研究对比了不同推力分配方案在执行高机动性翻转动作时的稳定性、能耗效率与响应速度,旨在提升无人机在复杂飞行任务中的动态性能与控制精度。该仿真研究为无人机飞控系统的设计与优化提供了理论依据和技术支持。; 适合人群:具备一定自动控制理论基础和Matlab编程能力,从事无人机控制、飞行器动力学或机器人系统研究的科研人员及研究生。; 使用场景及目标:① 实现四旋翼无人机在三维空间中的精确点对点运动控制;② 对比分析不同推力分配策略在执行翻转等高难度动作时的控制效果与能耗表现,优化飞行性能;③ 为无人机自主飞行、特技飞行及复杂环境下的机动控制提供算法验证平台。; 阅读建议:此资源以Matlab仿真为核心,建议读者结合相关控制理论知识,深入理解代码实现细节,重点关注动力学建模、控制律设计与推力分配模块。在学习过程中,应动手调试参数,复现文中翻转动作的仿真结果,并尝试拓展至其他复杂飞行任务,以加深对无人机控制机理的理解。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值