比赛 2024.12.21 评测结果 AAAAAAAAAAAAAAAAAAAAAAAA
题目名称 Activating Robots 最终得分 100
用户昵称 健康铀 运行时间 7.963 s
代码语言 C++ 内存使用 182.08 MiB
提交时间 2024-12-21 17:00:43
显示代码纯文本
#include<bits/stdc++.h>
using namespace std;
unsigned long long n,r,a[3000005],f[1<<20][21],l,k,d[1000005][21],ans=-1;
unsigned long long js(unsigned long long x,unsigned long long y){
	if(x/y*y!=x)return x/y+1;
	return x/y;
}
void zdj(){
	for(long long i=0;i<=n;i++){
		for(long long j=0;j<=r;j++){
			unsigned long long num=0;
			if(k!=1)
			num=a[i]+j*(l/r)+min(js((r-j)*(l/r),k+1),js(j*(l/r),k-1));
            else 
			num=a[i]+j*(l/r)+js((r-j)*(l/r),k+1);
            long long l1=1,r1=3*n,mid;
            while(l1<r1){
                mid=(l1+r1)/2;
                if(a[mid]>=num)r1=mid;
                else l1=mid+1;
            }
            d[i][j]=k*(a[l1]-(a[i]+j*(l/r)));
		}
	}
}
int main(){
	freopen("activating_robots.in","r",stdin);
	freopen("activating_robots.out","w",stdout);
	ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
	memset(f,-1,sizeof(f));
	cin>>l>>r>>n>>k;
	for(long long i=1;i<=n;i++)
	cin>>a[i];
	sort(a+1,a+n+1);
	for(long long i=n+1;i<=3*n;i++)
	a[i]=a[i-n]+l;
	zdj();
	f[1][1]=0;
	for(long long i=1;i<(1<<r);i++){
		for(long long j=1;j<=r;j++){
			if(f[i][j]==-1)
			continue;
			if((i&(1<<j-1))==0)
			continue;
			if(j==1&&i==1){
				for(long long k1=1;k1<=r;k1++){
					if((i&(1<<(k1-1)))!=0)
					continue;
					long long v;
					if(k1>j)
					v=k1-j;
					else
					v=k1+r-j;
					if(f[i|(1<<(k1-1))][k1]==-1)
					f[i|(1<<(k1-1))][k1]=f[i][j]+d[0][v];
					else
					f[i|(1<<(k1-1))][k1]=min(f[i|(1<<(k1-1))][k1],f[i][j]+d[0][v]);
				}
				continue;
			}
			long long x=(j-1)*(l/r)+(f[i][j]/k);
			while(x>=l)
			x-=l;
			long long l1=1,r1=n+1,mid=0;
			while(l1<r1){
                mid=(l1+r1)/2;
                if(a[mid]>=x)r1=mid;
                else l1=mid+1;
            }
            if(l1>n)
            l1-=n;
            for(long long k1=1;k1<=r;k1++){
				if((i&(1<<(k1-1)))!=0)
				continue;
				long long v;
				if(k1>j)
				v=k1-j;
				else
				v=k1+r-j;
				if(f[i|(1<<(k1-1))][k1]==-1)
				f[i|(1<<(k1-1))][k1]=f[i][j]+d[l1][v];
				else
				f[i|(1<<(k1-1))][k1]=min(f[i|(1<<(k1-1))][k1],f[i][j]+d[l1][v]);
			}
		}
	}
	for(long long i=1;i<=r;i++){
		if(f[(1<<r)-1][i]==-1)
		continue;
		if(ans==-1)
		ans=f[(1<<r)-1][i];
		else
		ans=min(ans,f[(1<<r)-1][i]);
	}
	cout<<ans;
	return 0;
}