2023-10-04 08:08阅读: 59评论: 0推荐: 1

『题解』P9688

题目传送门

思路:

设有两个颜色 x1x2 ,两端分别为 l1 r1l2 r2。通过观察可以发现,若满足 x1<x2r1>l2x1x2 一定是单调不下降的。

那么我们可以先预处理出一个颜色可以与前面的哪些颜色构成单调不下降,然后用dp求出最终答案。

fi j 为选择第 i 个颜色,选择了 j 个颜色时的最大价值。设可以与 i 颜色构成单调不下降的颜色为 l。转移方程为fi j=max fi j fl j1

时间复杂度是O(N2K)

code:

#include <iostream>
#include <vector>
#include <cstring>
#define int long long
using namespace std;
const int Max = 5e2+10;
int n,k;
int a[Max],b[Max];
int l[Max],r[Max];
vector<int>m[Max],c[Max];
int f[Max][Max],ans;
inline int read(){
    int num=0,fl=1;char c=getchar();
    while(c<'0'||c>'9'){
        if(c=='-') fl=-1;
        c=getchar();
    }
    while(c >='0'&&c <='9'){
        num=(num<<3)+(num<<1)+(c^48);
        c=getchar();
    }
    return num*fl;
}
signed main(){
    memset(f,-0x3f,sizeof f);
    n=read(),k=read();
    for(int i = 1;i <= n;i++){
        a[i]=read();
        m[a[i]].push_back(i);
        if(!l[a[i]])l[a[i]]=i;
        r[a[i]]=i;
    }
    for(int i = 1;i <= n;i++){
        b[i]=read();
    }
    for(int i = 1;i <= n;i++){ //预处理
        if(!m[i].empty()){
            for(int j = 1;j < i;j++){
            	if(!m[j].empty()){
            		if(r[j]<l[i]){
            			c[i].push_back(j);
					}
				}
			}
        }
    }
    f[0][0]=0;//dp初始化
    for(int i = 1;i <= n;i++){
        if(!m[i].empty()){
            f[i][1]=b[i];
        }
    }
    for(int i = 1;i <= n;i++){//dp
        if(!m[i].empty()){
            for(int j = 2;j <= k;j++){
                for(int l=0;l<c[i].size();l++){
                    f[i][j]=max(f[i][j],f[c[i][l]][j-1]+b[i]);
                }
            }    
        }
    }
    for(int i = 1;i <= n;i++){
        ans=max(ans,f[i][k]);
    }
    if(ans==0)printf("-1");
    else printf("%lld",ans);
    return 0;  
}
posted @   tkt  阅读(59)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起