Topcoder SRM 718 div1 level three 题解

Topcoder SRM 718 div1 level three 题解

结论题:

首先考虑\(f(p,|p|-1)=|p|\)的情况。

经过打表发现必须存在相邻两个元素相邻。

简单证明即可推广到一般情况:

\(f(p,|p|-k)\neq {|p|\choose k}\),当且仅当\(\exists_{i,j} |i-j|+|a_i+a_j|\leq k+1\)

直接爆搜+剪枝即可。

code:

/*
{
######################
#       Author       #
#        Gary        #
#        2021        #
######################
*/
#include<bits/stdc++.h>
#define rb(a,b,c) for(int a=b;a<=c;++a)
#define rl(a,b,c) for(int a=b;a>=c;--a)
#define LL long long
#define IT iterator
#define PB push_back
#define II(a,b) make_pair(a,b)
#define FIR first
#define SEC second
#define FREO freopen("check.out","w",stdout)
#define rep(a,b) for(int a=0;a<b;++a)
#define SRAND mt19937 rng(chrono::steady_clock::now().time_since_epoch().count())
#define random(a) rng()%a
#define ALL(a) a.begin(),a.end()
#define POB pop_back
#define ff fflush(stdout)
#define fastio ios::sync_with_stdio(false)
#define check_min(a,b) a=min(a,b)
#define check_max(a,b) a=max(a,b)
using namespace std;
//inline int read(){
//    int x=0;
//    char ch=getchar();
//    while(ch<'0'||ch>'9'){
//        ch=getchar();
//    }
//    while(ch>='0'&&ch<='9'){
//        x=(x<<1)+(x<<3)+(ch^48);
//        ch=getchar();
//    }
//    return x;
//}
const int INF=0x3f3f3f3f;
typedef pair<int,int> mp;
/*}
*/
const int MAXN=12;
vector<int> Ans[MAXN<<2];
int best=0,n;
vector<int> A;
vector<int> Now;
void dfs(int now,int mn,int mask){
	if(mn<=best){
	 	return ;	
	}
	if(now==n){
		if(mn==INF) mn=0;
		Ans[mn]=Now;
		best=mn;
		return ;
	}
	if(A[now]!=-1){
		int pt=A[now];
		int Tmp=INF;
		rep(i,Now.size()){
			check_min(Tmp,int(Now.size())-i+abs(pt-Now[i]));
		}
		Now.PB(pt);
		dfs(now+1,min(mn,Tmp),mask);
		Now.POB();
	}
	else{
		rep(pt,n){
			if((mask>>pt)&1){
				int Tmp=INF;
				rep(i,Now.size()){
					check_min(Tmp,int(Now.size())-i+abs(pt-Now[i]));
				}
				Now.PB(pt);
				dfs(now+1,min(mn,Tmp),mask^(1<<pt));
				Now.POB();
			}
		}
	}
}
class PermutationSubsequence{
	public:
		vector<int> findBest(vector<int> a){
			n=a.size();
			A=a;
			int mask=(1<<n)-1;
			for(auto it:a) if(it!=-1) mask^=1<<it;
//			cout<<mask<<endl;
			dfs(0,INF,mask);
			rl(i,n<<1,0){
				if(!Ans[i].empty()) return Ans[i];
			}
			return {};
		}
}solver;
//int main(){
//	vector<int> ans=solver.findBest(	
//	
////	{7,2,5,3,4,0,6,1}
//{-1}
//
//);
//	for(auto it:ans){
//		cout<<it<<" ";
//	}
//	cout<<endl;
//	return 0;
//}

posted @ 2021-05-27 23:43  WWW~~~  阅读(66)  评论(0编辑  收藏  举报