75ptsTLE求剪枝
查看原帖
75ptsTLE求剪枝
467324
LuoMuxiaoxiao楼主2024/8/19 10:04
#include<bits/stdc++.h>
using namespace std;

const int N = 1000+5;

inline int read()
{
	int x(0); char ch = getchar();
	for(; !isdigit(ch); ch=getchar());
	for(; isdigit(ch); ch=getchar())
	x = (x << 1) + (x << 3) + (ch ^ 48);
	return x;
}

int n, a[N], l[N], sum, b, maxx, minn = INT_MAX, le;
bool ret;
bitset<N> vis;

inline bool cmp(int a, int b)
{
	return a>b;
}

void dfs(int len, int num, int idx)
{
	//up1 加入flag1, flag2无明显变化, 可行性剪枝
	//up2 加入idx 
	//printf("arrive%d\n", num);
	if(num == b) {
		ret = true;
		return;
	}
	if(l[num]+minn>len){
		return;
	}
	if(l[num]+le<len) {
		return;
	}
	if(ret) {
		return;
	}
	if((a[len-l[num]])){
		//printf("	add2 stick(%d, %d) to %d\n", len-l[num], a[len-l[num]], num);
		//l[num] += a[i];
		a[len-l[num]]--;
		le-=len-l[num];
		dfs(len, num+1, maxx);
		a[len-l[num]]++;
		le+=len-l[num];
		//l[num] -= a[i];
		if(ret) return;
	}
	else {
		if(l[num]) {
			for(int i = min(idx, len-l[num]); i >= minn; i--) {
				//printf("	tryl %d %d %d %d\n", i, a[i], num, l[num]);
				if(!a[i]) continue;
				if(ret) return;
				if(l[num]+i<=len) {
					//printf("	add1 stick(%d, %d) to %d\n", i, a[i], num);
					l[num] += i;
					a[i]--;
					le-=i;
					dfs(len, num, i);
					a[i]++;
					le+=i;
					l[num] -= i;
					if(ret) return;
					//
					//
				}
				if(l[num]==0){
					return;
				}
			}
		}
		else {
			for(int i = maxx; i >= minn; i--) {
				//printf("	tryl %d %d %d %d\n", i, a[i], num, l[num]);
				if(!a[i]) continue;
				if(ret) return;
				if(l[num]+i<=len) {
					//printf("	add1 stick(%d, %d) to %d\n", i, a[i], num);
					l[num] += i;
					a[i]--;
					le-=i;
					dfs(len, num, i);
					a[i]++;
					le+=i;
					l[num] -= i;
					if(ret) return;
					//
					//
				}
					return;
			}
		}
	}
	return;
}

int main()
{
	scanf("%d", &n);
	for(int i=1, t; i<=n; i++) {
		scanf("%d", &t); if(t<=50) a[t]++, sum+=t, maxx = max(t, maxx), minn = min(t, minn);
	}
//	printf("%d %d %d %d\n", n, sum, maxx, minn);
//	for(int i=minn; i<=maxx; i++)
//		printf("%d ", a[i]);
//	printf("\n");
	
	le = sum;
	for(b=n; b>1; b--) {
		if(sum%b==0 && sum/b>=maxx) {
			//printf("try%d %d\n", b, sum/b);
			dfs(sum/b, 0, maxx);
			if(ret) {
				printf("%d\n", sum/b);
				return 0;
			}
		}
	}
	printf("%d\n", sum);
	return 0;
}

球球了

2024/8/19 10:04
加载中...