这题还算是一道比较基础的动态规划问题啦, 和01背包问题略有类似, 都需要考虑容量和复杂度优化, 之前定义状态总想着能二维就二维, 现在看来很多时候其实可以直接用一维的思路去定义状态, 反而会简便很多
定义dp[i] : 前i个地点产生的最大利润(题目给出已排序的坐标, 省去了排序)
然后考虑到对于每个地点我们都有选与不选两种操作, 考虑需要再添加一个循环j : 来考虑第j个地点是否会是最优解
切记dp[i]的初始化就是d[i], 也就是到第i个地点至少的利润, 再注意判断相距要大于d
可得状态转移方程: dp[i] = dp{dp[i], dp[j] + d[i] | dp[i] - dp[j] > k}
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <vector>
#include <queue>
#include <cmath>
using namespace std;
#define ms(x, n) memset(x,n,sizeof(x));
typedef long long LL;
const LL maxn = 110;
int T, n, k;
int p[maxn], m[maxn];
int dp[maxn]; //在前i个餐馆里取得的最大价值
int solve()
{
for(int i = 1; i <= n; i++) //i表示第i个餐馆
for(int j = 1; j < i; j++){ //找到一个最大价值的位置
if(m[i] - m[j] > k)
dp[i] = max(dp[i], dp[j]+p[i]);
}
int ans = 0;
for(int i = 1; i <= n; i++)
ans = max(dp[i], ans);
return ans;
}
int main()
{
cin >> T;
while(T--){
cin >> n >> k;
for(int i = 1; i <= n; i++)
cin >> m[i];
for(int i = 1; i <= n; i++){
cin >> p[i];
dp[i] = p[i];
}
cout << solve() << endl;
}
return 0;
}