求助剪枝思路
查看原帖
求助剪枝思路
409774
Maysoul楼主2023/8/27 17:08

思路是对每一个剩下的部分进行分割,同时记录其总分,最后计算标准差。

依照这个思路会超时,只有40pts。

考虑过维护极差进行大体的剪枝,但是很容易被hack掉。

想知道能否通过剪枝或其他手段来实现这种思路。

//2023/8/27
//别着急,先通读一遍题目
//别忘了开long long
//写完先看一遍怎么降复杂度
//要么开全局变量要么给定初值
//想想看,有什么情况需要特判
//看看数组开的够不够大
//std::ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
#include<bits/stdc++.h>
#define int long long 
using namespace std;
const int MAXN=1e6+10;
int num;
double ans=INT_MAX;
int dp[10][10][10][10];
int a[10][10],arr[10][10];
int calc(int x1,int y1,int x2,int y2)
{
	int tot=arr[x2][y2]-arr[x1-1][y2]-arr[x2][y1-1]+arr[x1-1][y1-1];
	return tot;
}
void update(vector<int> &vec)
{
	/*for (int i:vec){
		cout<<i<<" ";
	}
	cout<<endl;*/
	double sum=accumulate(vec.begin(),vec.end(),0.0);
	double siz=vec.size();
	double pj=sum/siz,les=0;
	for (double i:vec){
		les+=(i-pj)*(i-pj);
	}
	les=sqrt(les/siz);
	//cout<<les<<endl;
	ans=min(les,ans);
	return;
}
void dfs(int x1,int y1,int x2,int y2,vector<int> vec,int used)
{
	if(used==0){
		vec.push_back(calc(x1,y1,x2,y2));
		update(vec);
		return;
	}
	vector<int> temp=vec;
	for (int i=x1;i<x2;i++){
		temp.push_back(calc(i+1,y1,x2,y2));
		dfs(x1,y1,i,y2,temp,used-1);
		temp.pop_back();
		temp.push_back(calc(x1,y1,i,y2));
		dfs(i+1,y1,x2,y2,temp,used-1);
		temp.pop_back();
	}
	for (int i=y1;i<y2;i++){
		temp.push_back(calc(x1,y1,x2,i));
		dfs(x1,i+1,x2,y2,temp,used-1);
		temp.pop_back();
		temp.push_back(calc(x1,i+1,x2,y2));
		dfs(x1,y1,x2,i,temp,used-1);
		temp.pop_back();
	}
}
signed main()
{
	int n;
	cin>>n;
	for (int i=1;i<=8;i++){
		for (int j=1;j<=8;j++){
			cin>>a[i][j];
		}
	}
	for (int i=1;i<=8;i++){
		for (int j=1;j<=8;j++){
			arr[i][j]=arr[i-1][j]+arr[i][j-1]-arr[i-1][j-1]+a[i][j];
		}
	}
	vector<int> v;
	dfs(1,1,8,8,v,n-1);
	printf("%.3f",ans);
	return 0;
}
2023/8/27 17:08
加载中...