思路是对每一个剩下的部分进行分割,同时记录其总分,最后计算标准差。
依照这个思路会超时,只有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;
}