P9688 Colo. 题解
题目分析
我们发现“从左到右颜色的编号是单调不下降的”,可以联想到经典 DP 问题:最长单调不下降子序列。因此这一题可以参考最长不降序列的写法。
注:本人思路并非最好,但个人认为较好理解。
设计状态转移方程:
推出转移式子后,只剩下判断每个
这里除了要判断
具体见代码实现。
#include<bits/stdc++.h>
using namespace std;
#define ull unsigned long long
#define ll long long
#define INF 0x3f3f3f3f
#define re register
#define il inline
#define gc getchar
#define int ll //记得开long long!
const int N = 505;
int n,k,a[N],b[N],dp[N][N],from[N],bk[N],pre[N];
signed main()
{
memset(bk,-1,sizeof bk);
memset(pre,-1,sizeof pre);
cin >> n >> k;
for (int i = 1;i <= n;i++) scanf("%lld",&a[i]);
for (int j = 1;j <= n;j++) scanf("%lld",&b[j]);
for (int i = 1;i <= n;i++) dp[i][1] = b[a[i]];
//预处理出每个颜色最前和最后所在位置
for (int i = 1;i <= n;i++)
if (pre[a[i]] == -1) pre[a[i]] = i;
for (int i =n;i >= 1;i--)
if (bk[a[i]] == -1) bk[a[i]] = i;
for (int e = 1;e <= k;e++) //枚举保留k个
for (int i = 1;i <= n;i++) //枚举以第i个结尾
for (int j = 1;j < i;j++) // 用第j个转移
if (a[j] < a[i] && bk[a[j]] < pre[a[i]] && dp[j][e-1])
{
//状态转移
dp[i][e] = max(dp[i][e],dp[j][e-1]+b[a[i]]);
}
int res = 0;
for (int i = 1;i <= n;i++) res = max(res,dp[i][k]);
if (!res) puts("-1");
else cout << res << endl;
return 0;
}
分类:
题解
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】