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

【羊圈——状压 + DP / 记忆化搜索DP】

题目

一般DP代码(注意,这里只能向外推(起始状态是f(1,0),不能向内推(不然会导致之前的羊圈被割裂))

#include <bits/stdc++.h>
using namespace std;const int MAX_N = 210;
const int MAX_M = 16;int n, m;
double p[MAX_N];
int l[MAX_M];
double dp[MAX_N][1 << MAX_M];int main() {cin >> m >> n;for (int i = 1; i <= m; i++) cin >> l[i];for (int i = 1; i <= n; i++) cin >> p[i];int mask = 1 << m;for (int i = 0; i <= n + 1; i++) {for (int j = 0; j < mask; j++) {dp[i][j] = 1e18;}}dp[1][0] = 0;for (int u = 1; u <= n; u++) {for (int s = 0; s < mask; s++) {if (dp[u][s] == 1e18) continue;// 不覆盖当前羊uif (u + 1 <= n + 1) {dp[u + 1][s] = min(dp[u + 1][s], dp[u][s] + p[u]);}// 尝试用未使用的羊圈i覆盖for (int i = 1; i <= m; i++) {if (!(s & (1 << (i - 1))) && u + l[i] - 1 <= n) {int new_s = s | (1 << (i - 1));dp[u + l[i]][new_s] = min(dp[u + l[i]][new_s], dp[u][s]);}}}}double ans = 1e18;for (int s = 0; s < mask; s++) {ans = min(ans, dp[n + 1][s]);}printf("%.2lf\n", ans);return 0;
}

记忆化搜索DP代码

#include <bits/stdc++.h>
using namespace std;
using db = double;int n, m;
db p[210];
int w[20];
db dp[210][(1 << 15) + 10];db f(int u, int s)
{if(u >= n+1) return 0;if(dp[u][s] != -1) return dp[u][s];db ret = 1e18;//不用,状态不变,但是值要增加(这里的值指的是逃跑期望)ret = p[u] + f(u+1, s);//用for(int i = 1; i <= m; i++){if(!(s & (1 << (i-1))) && u + w[i] - 1 <= n){ret = min(ret, f(u+w[i], s | (1 << (i-1))));}}return dp[u][s] = ret;
}
int main()
{cin >> m >> n;for(int i = 1; i <= m; i++)cin >> w[i];for(int i = 1; i <= n; i++)cin >> p[i];for(int i = 1; i <= n; i++)	for(int j = 0; j < 1 << m; j++)dp[i][j] = -1;printf("%.2lf", f(1, 0));
}

感想

另外勘误

这题很多解法都是没看到“最多”吗

为什么要加这个限制?

#include <bits/stdc++.h>
using namespace std;
using db = double;int n, m;
db p[210];
int w[20];
db dp[210][(1 << 15) + 10];db f(int u, int s)
{if(u >= n+1) return 0;if(dp[u][s] != -1) return dp[u][s];db ret = 1e18;//不用,状态不变,但是值要增加(这里的值指的是逃跑期望)ret = p[u] + f(u+1, s);//用for(int i = 1; i <= m; i++){if(!(s & (1 << (i-1)))){ret = min(ret, f(u+w[i], s | (1 << (i-1))));}}return dp[u][s] = ret;
}
int main()
{cin >> m >> n;for(int i = 1; i <= m; i++)cin >> w[i];for(int i = 1; i <= n; i++)cin >> p[i];for(int i = 1; i <= n; i++)	for(int j = 0; j < 1 << m; j++)dp[i][j] = -1;printf("%.2lf", f(1, 0));
}

相关文章:

  • vue 水印组件
  • 第三十四天打卡
  • 线程的一些基本知识
  • FME入门系列教程7-基于FME的ArcGIS空间数据互操作技术研究与实践
  • 青少年编程与数学 02-020 C#程序设计基础 03课题、开始编程
  • onnx模型转入rknn3399平台上工作记录
  • Axure元件动作五:设置列表选中项
  • 蓝桥杯国14 互质
  • Vue+css实现扫描动画效果(使用@keyframes scan)
  • COZE工作流全场景变现新路径:小程序/网站封装集成
  • SDL2常用函数SDL事件处理:SDL_Event|SDL_PollEvent
  • 如何选择服务器机房托管服务?
  • OpenCV入门
  • Seata分布式事物案例及详解
  • 如何配置jmeter做分布式压测
  • Spring Boot + MyBatis-Plus实现操作日志记录
  • oracle数据库生成awr报告,排查数据库服务器CPU100%,系统卡顿,慢sql,根据sqlid查询关键信息,如会话SID,客户端机器名
  • MySQL 8.0 OCP 1Z0-908 题目解析(11)
  • MySQL 8.0 OCP 1Z0-908 题目解析(13)
  • 游戏引擎学习第307天:排序组可视化
  • 蒙牛网站建设报价情况/建站abc官方网站
  • 模板网恋/潮州seo建站
  • 做网站襄樊/百度网盘怎么找资源
  • 如何对自己做的php网站加密/直播营销
  • wordpress网站+搬家/安卓优化大师老版本下载
  • 天津市建设公司网站/电商平台运营方案