题解:B4172 [BCSP-X 2024 6 月小学高年级组] 学习计划
题目传送门
思路
最优化问题,考虑动态规划。
状态定义 :
由于收益的计算方式与子段和有关,所以我们在设计状态转移方程式要考虑继承 / 不继承 上次的子段和。
先考虑继承,即上一天(第
考虑不继承,即上一天选
综上,可得状态转移方程为
时间复杂度
还有几个小点需要注意:
- 总收益可能为负数,所以
dp 数组初始化成负无穷。 - 十年 OI 一场空,不开long long见祖宗。
Code
#include <bits/stdc++.h>
using namespace std;
#define il inline
typedef long long ll;
const int N = 2e3 + 10;
ll a[N], b[N];
ll dp[N][N];
int n, m;
il void init()
{
cin >> n >> m;
for(int i = 1;i <= n;++i)
scanf("%lld", &a[i]);
for(int i = 1;i <= m;++i)
scanf("%lld", &b[i]);
}
il void solve()
{
memset(dp, -0x3f, sizeof(dp));
dp[0][0] = 0;
for(int i = 1;i <= n;++i)
for(int j = 1;j <= m;++j)
dp[i][j] = max(dp[i - 1][j] + a[i] * b[j], dp[i - 1][j - 1] + a[i] * b[j]);
cout << dp[n][m] << "\n";
}
int main()
{
int t;
cin >> t;
while(t--)
{
init();
solve();
}
return 0;
}