Array Division-dp
题意:
给你两个数组 a b长度都为n 让你将它们分成尽可能多的k段(连续的) 分法一致且满足每一段al到ar的和比对应bl到br的和大 求最大的k
思路:
dp[i] 代表前i个最多能分多少个
从左到右枚举左边界 然后枚举右边界 判断当前l 到r 这段区间是否满足条件 如果满足就更新dp[r] 转移方程:dp[r] = max(dp[r], dp[l] + 1)
#include<iostream> #include<algorithm> #include<string> #include<set> #include<map> #include<cstdio> #include<cmath> #include<cstring> #include<queue> #include<stack> #include<unordered_map> #include<iomanip> #define ll long long #define ull unsigned long long #define IOS ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr) #define m_p make_pair #define pi acos(-1) using namespace std; const int N = 5e5 + 5; const double eps = 1e-4; const int inf = 0x3f3f3f3f; const ll INF = 0x3f3f3f3f3f3f3f3f; const int mod = 1e9 + 7; ll n, a[5010], b[5010], pre[5010], dif[5010]; string s; ll dp[5010]; void solve() { cin >> n; pre[0] = 0; for(int i = 1; i <= n; i++){ cin >> a[i]; } for(int i = 1; i <= n; i++){ cin >> b[i]; //预处理 记录a与b对应元素的差 以及 差的前缀和 dif[i] = a[i] - b[i]; pre[i] = pre[i - 1] + dif[i]; } dp[0] = 0; //初始化为-1 for(int i = 1; i <= n; i++){ dp[i] = -1; } for(int i = 0; i <= n; i++){ //如果dp[i]为-1 就代表前面没有更新过 说明不能将i作为左边界 故继续 if(dp[i] == -1) continue; for(int j = i + 1; j <= n; j++){ //如果该区段为正就更新 if(pre[j] - pre[i] >= 0) dp[j] = max(dp[j], dp[i] + 1); } } cout << dp[n] << "\n"; } signed main() { IOS; ll t = 1; cin >> t; while(t--) solve(); return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律