Array Division-dp

Array Division

题意:

给你两个数组 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;
}
复制代码

 

 

posted @   Yaqu  阅读(60)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示