ARC 100

C

原式$\sum{|a_i-(b+i)|}$可以转化为$\sum{|(a_i-i)-b|}$

$b_i=a_i-i$

即求$\sum{|b_i-b|}$,

D

先要想到切中间那刀。

方法一:piont to point

方法二:二分答案(ggg)

E

$i or j\leq k$可以转化为$i or j=k$和$i or j\leq k-1$

后一式子可以通过$k-1$转移

讨论$i or j=k$的情况

 

#include<bits/stdc++.h>
using namespace std;
const long long N=1<<19;
long long a[N];
long long n,pp;
struct re{
	long long num;
	long long id;
}x[5],dp[N][2];
long long maxer;
short p[N];
bool cmp(re x,re y){return x.num<y.num;}
int main()
{	
freopen	("p.in","r",stdin);

freopen("p.out","w",stdout);
	ios::sync_with_stdio(0);
	cin>>n;
	pp=(1<<n)-1;
	for(long long i=0;i<=pp;i++){
	long long c;
	cin>>a[i];
	dp[i][0].num=a[i];
	dp[i][0].id=i;
	dp[i][1].id=-100;
	}
	for(long long i=1;i<pp;i++){
		for(long long j=0;j<n;j++)if((1<<j)&i){
		long long k=(1<<j)^i;
		x[1]=dp[k][0];
		x[2]=dp[k][1];
		x[3].num=a[i];
		x[4].num=a[1<<j];
		x[3].id=i;
		x[4].id=1<<j;
		sort(x+1,x+1+4,cmp);
		int az=0,s;
		for(int l=4;l>=1;l--)
			if(x[l].num>dp[i][0].num){
			az=1;
			re ax=dp[i][0];
			dp[i][0]=x[l];
			x[l]=ax;
			break;}
		for(int l=4;l>=1;l--)
			if(x[l].num>dp[i][1].num&&dp[i][0].id!=x[l].id)
			{dp[i][1]=x[l];}	
		}
		maxer=max(maxer,dp[i][1].num+dp[i][0].num);
		cout<<maxer<<endl;
	}
	long long i=pp;
	for(long long j=0;j<n;j++)if((1<<j)&i){
		long long k=(1<<j)^i;
		x[1]=dp[k][0];
		x[2]=dp[k][1];
		x[3].num=a[i];
		x[4].num=a[1<<j];
		x[3].id=i;
		x[4].id=1<<j;
		sort(x+1,x+1+4,cmp);
		int az=0,s;
		for(int l=4;l>=1;l--)
			if(x[l].num>dp[i][0].num){
			az=1;
			re ax=dp[i][0];
			dp[i][0]=x[l];
			x[l]=ax;
			break;}
		for(int l=4;l>=1;l--)
			if(x[l].num>dp[i][1].num&&dp[i][0].id!=x[l].id)
			{dp[i][1]=x[l];}	
		}
		maxer=max(maxer,dp[i][1].num+dp[i][0].num);
		cout<<maxer<<endl;
	return 0;
}

 

posted @ 2019-01-30 16:30  周栎  阅读(169)  评论(0编辑  收藏  举报