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

【Luogu】动态规划七

P1566 加等式 - 洛谷

思路:

其实这道题就是一个纸老虎,说这么多,其实最后就是问所有 a[i] 的组成方法之和有多少种

那么显然的一个dp就是 dp[j] += dp[j - a[i]]

然后这题就结束了,就是这么简单,最后记得减去 n,因为 a[i] 可由自己组成,但是题目说了必须要由其他数组成

代码:

#include <iostream>
#include <algorithm>
#include<cstring>
#include <iomanip>
#include<cctype>
#include<string>
#include <set>
#include <vector>
#include <cmath>
#include <queue>
#include <unordered_set>
#include <map>
#include <unordered_map>
#include <stack>
#include <utility>
#include <array>
#include <tuple>
using namespace std;
#define int long long
#define yes cout << "YES" << endl
#define no cout << "NO" << endlvoid solve()
{int n;cin >> n;vector<int> dp(30005,0),a(n);for (int i = 0; i < n; i++){cin >> a[i];}dp[0] = 1;for (int i = 0; i < n; i++){for (int j = 30000; j >= a[i]; j--){dp[j] += dp[j - a[i]];}}int res = -n;for (int i = 0; i < n; i++){res += dp[a[i]];}cout << res << endl;
}
signed main()
{cin.tie(0)->sync_with_stdio(false);int t = 1;cin >> t;while (t--){solve();}return 0;
}

P3133 [USACO16JAN] Radio Contact G - 洛谷

思路:

这题有两个人,根据问什么设什么,我们能简单想到一个dp,就是 dp[i][j] 其代表的含义就是前一个人走了 i 步,后一个人走了 j 步的最小花费

那么这个就有四种转移,分别是

①.第一个人不走,第二个人走

②.第一个人走,第二个人不走

③.两个人都走

④.两个人都不走

显然④不可能出现,所以只需要转移前三种情况了

那么转移就是 dp[i][j] = min(1,2,3) + dis(i,j),其中 dis(i,j) 是第一个人走了i步后的坐标与第二个人走了j步后的坐标的举例

代码:

#include <iostream>
#include <algorithm>
#include<cstring>
#include <iomanip>
#include<cctype>
#include<string>
#include <set>
#include <vector>
#include <cmath>
#include <queue>
#include <unordered_set>
#include <map>
#include <unordered_map>
#include <stack>
#include <utility>
#include <array>
#include <tuple>
using namespace std;
#define int long long
#define yes cout << "YES" << endl
#define no cout << "NO" << endl
int dp[1005][1005];
pair<int, int> f[1005], b[1005];
map<char, pair<int, int>> dir;int dis(int u,int v)
{return pow(f[u].first - b[v].first, 2) + pow(f[u].second - b[v].second, 2);
}void solve()
{int n, m;cin >> n >> m;cin >> f[0].first >> f[0].second;cin >> b[0].first >> b[0].second;dir['N'] = {0,1}, dir['E'] = {1,0}, dir['S'] = {0,-1}, dir['W'] = {-1,0};for (int i = 1; i <= n; i++){char c;cin >> c;f[i].first = f[i - 1].first + dir[c].first;f[i].second = f[i - 1].second + dir[c].second;}for (int i = 1; i <= m; i++){char c;cin >> c;b[i].first = b[i - 1].first + dir[c].first;b[i].second = b[i - 1].second + dir[c].second;}for (int i = 1; i <= n; i++) dp[i][0] = dp[i - 1][0] + dis(i, 0);for (int i = 1; i <= m; i++)dp[0][i] = dp[0][i - 1] + dis(0, i);for (int i = 1; i <= n; i++){for (int j = 1; j <= m; j++){dp[i][j] = min(dp[i - 1][j - 1], min(dp[i - 1][j], dp[i][j - 1])) + dis(i, j);}}cout << dp[n][m];
}
signed main()
{//cin.tie(0)->sync_with_stdio(false);int t = 1;//cin >> t;while (t--){solve();}return 0;
}

P2734 [USACO3.3] 游戏 A Game - 洛谷

思路:

区间dp,很有意思

题目让我们求取的最大值,这道题显然可以用dp

我们定义 dp[i][j] 为 i ~ j 区间内先手的人能取得的最大值

那么转移也就很明显了,由于每次我们只能取两边的数,所以对于 dp[i][j] 就可以从 dp[i+1][j] 或 dp[i][j-1] 转移来,那么具体方程怎么写呢?

其实就是 dp[i][j] = max(s - dp[i+1][j],s - dp[i][j-1]) 其中 s 是区间 i~j 的和

那为什么是这样转移呢?我们假设当前是第一个人选,那么之前就是第二个人选,那第二个人也是按最优的选法选的,那么他的值就是 dp[i+1][j] 或 dp[i][j-1] 中的较小值(毕竟是后手),所以我们取max即可

注意初始化以及枚举顺序,这里我们枚举大到小枚举左端点,然后从小到大枚举右端点

代码:

#include <iostream>
#include <algorithm>
#include<cstring>
#include <iomanip>
#include<cctype>
#include<string>
#include <set>
#include <vector>
#include <cmath>
#include <queue>
#include <unordered_set>
#include <map>
#include <unordered_map>
#include <stack>
#include <utility>
#include <array>
#include <tuple>
using namespace std;
#define int long long
#define yes cout << "YES" << endl
#define no cout << "NO" << endl
int f[105][105];
void solve()
{int n;cin >> n;vector<int> a(n+1),sum(n+1);for (int i = 1; i <= n; i++){cin >> a[i];sum[i] = sum[i - 1] + a[i];f[i][i] = a[i];}for (int i = n - 1; i >= 1; i--){for (int j = i + 1; j <= n; j++){int s = sum[j] - sum[i - 1];f[i][j] = max(s - f[i + 1][j],s- f[i][j - 1]);}}cout << f[1][n] << " " << sum[n] - f[1][n];
}
signed main()
{//cin.tie(0)->sync_with_stdio(false);int t = 1;//cin >> t;while (t--){solve();}return 0;
}

P3004 [USACO10DEC] Treasure Chest S - 洛谷

思路:

上面这题的双倍经验,思路一模一样,但是要优化空间复杂度

我们发现 dp[i][j] 的转移只与当前区间长度减一的区间有关,所以我们可以定义 dp[i] 为 以 i 为起点区间长度为 len 时的最大值,然后枚举从小到大枚举区间长度,从小到大枚举左端点即可

代码:

#include <iostream>
#include <algorithm>
#include<cstring>
#include <iomanip>
#include<cctype>
#include<string>
#include <set>
#include <vector>
#include <cmath>
#include <queue>
#include <unordered_set>
#include <map>
#include <unordered_map>
#include <stack>
#include <utility>
#include <array>
#include <tuple>
using namespace std;
#define int long long
#define yes cout << "YES" << endl
#define no cout << "NO" << endl
int f[5001];
int sum[5001],a[5001];
void solve()
{int n;cin >> n;for (int i = 1; i <= n; i++){cin >> a[i];sum[i] = sum[i - 1] + a[i];}for (int len = 1; len <= n; len++) {for (int i = 1; i + len - 1 <= n; i++) { // i 是区间的起始位置int j = i + len - 1; // 结束位置int s = sum[j] - sum[i - 1]; // 当前区间的和if (len == 1) {f[i] = a[i]; // 只有一个元素的情况}else {f[i] = max(s - f[i + 1], s - f[i]); // 状态转移}}}cout << f[1];
}
signed main()
{//cin.tie(0)->sync_with_stdio(false);int t = 1;//cin >> t;while (t--){solve();}return 0;
}

http://www.xdnf.cn/news/210691.html

相关文章:

  • 3D Gaussian Splatting部分原理介绍和CUDA代码解读
  • 实验六 文件操作实验
  • 计算机视觉与深度学习 | 双目立体匹配算法理论+Opencv实践+matlab实践
  • 20250429-李彦宏口中的MCP:AI时代的“万能接口“
  • hover加图层图放大
  • 多块盘创建RAID5以及后增加空间
  • shell(4)
  • UBUS 通信接口的使用——添加一个object对象(ubus call)
  • 开放平台架构方案- GraphQL 详细解释
  • 2025年- H13-Lc120-189.轮转数组(普通数组)---java版
  • Cliosoft安装
  • 【AI学习】李宏毅新课《DeepSeek-R1 这类大语言模型是如何进行「深度思考」(Reasoning)的?》的部分纪要
  • 大屏 UI 设计:解锁视觉盛宴的奥秘
  • Microsoft .NET Framework 3.5 离线安装包 下载
  • python celery框架结合django的使用
  • 爬虫学习笔记(五)---数据解析之re
  • 【最新 MCP 战神手册 09】利用资源和提示增强上下文
  • Linux批量管理:Ansible自动化运维指南
  • 飞蛾扑火算法优化+Transformer四模型回归打包(内含MFO-Transformer-LSTM及单独模型)
  • 开源Kotlin从零单排0基础完美入门教程
  • 第十六届蓝桥杯 2025 C/C++组 破解信息
  • 绿色版的notepad++怎么加入到右键菜单里
  • 深度学习---pytorch搭建深度学习模型(附带图片五分类实例)
  • 【docker】启动临时MongoDB容器、挂载数据卷运行数据库服务,并通过备份文件恢复MongoDB数据库备份数据
  • MCP 架构全解析:Host、Client 与 Server 的协同机制
  • Spring MVC 中解决中文乱码问题
  • 解决STM32H743单片机USB_HOST+FATF操作usb文件
  • 代码随想录算法训练营 Day35 动态规划Ⅲ 0-1背包问题
  • Python数据处理:文件的自动化重命名与整合
  • JavaWeb:后端web基础(TomcatServletHTTP)