#include<bits/stdc++.h>
#define MAXN 505
using namespace std;
int n,k;
int col[MAXN];
long long val[MAXN];
bool vis[MAXN];
struct node{
int pre,last;
}pos[MAXN];
vector<int>out;
bool cantget[MAXN][MAXN];
bool comeout[MAXN];
long long ans;
int minn[MAXN];
typedef pair<long long ,int >arr;
priority_queue<arr,vector<arr>,greater<arr> >que;
void dfs(int now,int tot,long long sum)
{
vis[now]=1;
if(tot==k)
ans=max(ans,sum);
for(int i=now+1;i<=n;++i)
{
if(pos[i].last==0||pos[i].pre<pos[now].last)continue;
if(tot<k)
{que.push(arr(val[i],i));
dfs(i,tot+1,sum+val[i]);
}
if(tot==k)
{
int d=que.top().first;
if(d>=val[i])continue;
vis[que.top().second]=0;
que.pop();
que.push(arr(val[i],i));
dfs(i,tot,sum-d+val[i]);
}
}
}
bool cmp(int a,int b){return a<b;}
int main()
{
cin>>n>>k;
for(int i=1;i<=n;++i)
{
cin>>col[i];
pos[col[i]].last=i;
if(vis[col[i]]==0)
{pos[col[i]].pre=i;
out.push_back(col[i]);
}
vis[col[i]]=1;
comeout[col[i]]=1;
}
/*for(int i=1;i<=n;++i)
{
for(int j=1;j<=n;++j)
cout<<cantget[i][j]<<" ";
cout<<endl;
}*/
for(int i=1;i<=n;++i)
scanf("%d",&val[i]);
memset(vis,0,sizeof(vis));
sort(out.begin(),out.end(),cmp);
for(int i=0;i<out.size();++i)
{
dfs(out[i],1,val[out[i]]);
while(!que.empty())que.pop();
}
cout<<(ans==0?-1:ans)<<endl;
return 0;
}
思路大概看下就懂了,原本想先把MLE的处理成不MLE的,然后将顺推转逆推把优先队列的map消去(逆推的话处理的到去tot的时候一定是最优,然后像题解的取答案就是一个O(n3)的算法),但是MLE调半天没调处来:搜索一次我是这么计算的,转换成对每个点向前连边,最多有O(n2)条,遍历就是O(n2)的时间,处理n次就是O(n3).但是不知道是我写法问题还是剪枝问题,然后就不了了之,改了好久没改出来,有没有dalao帮下