社区讨论
基础赛T3 O(n²k)级别的算法过了??
灌水区参与者 9已保存回复 13
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 13 条
- 当前快照
- 1 份
- 快照标识符
- @lo17xlpg
- 此快照首次捕获于
- 2023/10/22 16:40 2 年前
- 此快照最后确认于
- 2023/11/02 16:30 2 年前
CPP
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
int n, k, t;
ll dp[510][510];
int l[510], r[510], val[510]; // 存储一个区间,l[i]代表i出现的最小下标,val代表i的价值
int a[510], b[510];
ll res;
int main(){
cin >> n >> k;
for (int i=1; i<=n; i++) { scanf("%d", &a[i]); }
for (int i=1; i<=n; i++) { scanf("%d", &b[i]); }
for (int i=1; i<=n; i++) { // 初始化区间数组
t = a[i];
if (!l[t]) {
l[t] = i, r[t] = i, val[t] = b[a[i]];
}
else{
r[t] = i;
}
}
// 处理dp数组。dp[i][j]代表已选用了i种颜色,且最右边一个选用的颜色为j时的价值
for (int i=1; i<=n; i++) { dp[1][i] = val[i]; } // 边界处理
// 核心代码 (写到这里才发现O(n^3)...)
for (int i=2; i<=k; i++){
for (int j=1; j<=n; j++){
for (int x=1; x<=l[j]; x++){
if (dp[i-1][a[x]] && x == r[a[x]] && a[x] < j){ // a[x]是一个区间的右边界,并且拼接后满足单调递增
dp[i][j] = max(dp[i][j], dp[i-1][a[x]] + val[j]);
}
}
}
}
for (int i=1; i<=n; i++) { res = max(res, dp[k][i]); }
if (res) { cout << res; }
else { cout << -1; }
return 0;
}
乱写的屎山,时间复杂度瓶颈应该在三重循环那里,是O(n²k),在n == k == 500,a中无重复元素的时候就是500^3 > 1e8,应该会TLE。
本来只想骗部分分,结果交上去不但AC了,甚至用时最长的点只有28ms???不知道是不是最内层循环的时间复杂度估计错了,求dalao解惑
回复
共 13 条回复,欢迎继续交流。
正在加载回复...