搜索求助
  • 板块P9688 Colo.
  • 楼主a_sad_soul
  • 当前回复3
  • 已保存回复3
  • 发布时间2023/10/2 20:20
  • 上次更新2023/11/2 16:28:33
查看原帖
搜索求助
456675
a_sad_soul楼主2023/10/2 20:20
#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;
}

思路大概看下就懂了,原本想先把MLEMLE的处理成不MLEMLE的,然后将顺推转逆推把优先队列的mapmap消去(逆推的话处理的到去tot的时候一定是最优,然后像题解的取答案就是一个O(n3)O(n^3)的算法),但是MLEMLE调半天没调处来:搜索一次我是这么计算的,转换成对每个点向前连边,最多有O(n2)O(n^2)条,遍历就是O(n2)O(n^2)的时间,处理nn次就是O(n3)O(n^3).但是不知道是我写法问题还是剪枝问题,然后就不了了之,改了好久没改出来,有没有dalao帮下

2023/10/2 20:20
加载中...