正解 88pts TLE 最后三个点求助
查看原帖
正解 88pts TLE 最后三个点求助
363036
chlchl楼主2023/10/8 22:37
#include<bits/stdc++.h>
#define int long long
using namespace std;

const int INF = 1e18;
const int N = 10000 + 5;
int n, mx, mmx, a[N], d[N], s[N], f[2][6000010];

main(){
	int now = 0, lst = 1;
	scanf("%lld", &n);
	for(int i=1;i<=n;i++){
		scanf("%lld", &a[i]);
		if(i > 1)
			d[i - 1] = a[i] - a[i - 1];
	}
	sort(d + 1, d + n);
	for(int i=1;i<n;i++)
		s[i] = s[i - 1] + d[i];
	mx = a[n], mmx = mx * n;
	int ct0 = 1;
	while(!a[ct0])
		++ct0;
	for(int i=0;i<=mmx;i++)
		f[now][i] = INF;
	f[now][d[ct0]] = d[ct0] * d[ct0];
	f[now][d[ct0] * ct0] = d[ct0] * d[ct0] * ct0;//后面已经有那么多个 d[ct0] 了 
	for(int i=ct0+1;i<n;i++){
		now ^= 1, lst ^= 1;
		for(int j=mmx;j>=0;j--)
			f[now][j] = INF;
		for(int j=mmx;j>=0;j--){//枚举 a[i] 的和 
			if(j + d[i] * i <= mx * n)
				f[now][j + d[i] * i] = min(f[now][j + d[i] * i], f[lst][j] + 2 * j * d[i] + d[i] * d[i] * i);//d[i] 放前面,后面每个数都会加上 d[i],所以要乘上 i 
			if(j + s[i] <= mx * n)
				f[now][j + s[i]] = min(f[now][j + s[i]], f[lst][j] + s[i] * s[i]);
		}
	}
	int ans = INF;
	for(int i=0;i<=mmx;i++)
		if(f[now][i] != INF)
			ans = min(ans, n * f[now][i] - i * i);
	printf("%lld\n", ans);
	return 0;
}
2023/10/8 22:37
加载中...