AcWing 321. Chessboard segmentation (interval dp)

Topic portal

Question: Give you a chessboard, you can cut a knife on the remaining part of the chessboard every time, and make sure that the remaining part after cutting is still a rectangle. Now we are going to use this rule to chop this chessboard into n pieces. The score of each piece is the sum of the numbers represented by each small square in this piece. Now we want you to find the smallest mean square error of these n pieces. (Standard deviation).

Idea: We can calculate σ 2 = 1 / n ∑ xi 2 − x ′ 2 (x ′ represents the average number) σ^2=1/n\sum x_i^2-x'^2 (x' represents the average number)σ2=1/nxi2x2(x' Tableshowsflat-averagenumber), then we can usef [k] [x 1]f [ k ] [ x 1 ] [ y 1 ] [ x 2 ] [ y 2 ] means(x 1, y 1) (x1,y1)(x1,y 1 ) is the upper left corner,(x 2, y 2) (x2,y2)(x2,y 2 ) is the rectangle in the lower right corner, cut k times, the smallest∑ xi 2 \sum x_i^2xi2, And then directly enumerate each rectangle, we have two transfer methods: horizontal cutting and vertical cutting, each time you cut the two pieces you have to consider which piece to continue cutting, that is, cut k-1 times. Finally, calculate the output according to the formula.

Code:

#include<bits/stdc++.h>
#define endl '\n'
#define null NULL
#define ls p<<1
#define rs p<<1|1
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define ll long long
//#define int long long
#define pii pair<int,int>
#define ull unsigned long long
#define pdd pair<double,double>
#define lowbit(x) x&-x
#define all(x) (x).begin(),(x).end()
#define sz(x) (int)(x).size()
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
char *fs,*ft,buf[1<<20];
#define gc() (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<20,stdin),fs==ft))?0:*fs++;
inline int read()
{
    
    
    int x=0,f=1;
    char ch=gc();
    while(ch<'0'||ch>'9')
    {
    
    
        if(ch=='-')
            f=-1;
        ch=gc();
    }
    while(ch>='0'&&ch<='9')
    {
    
    
        x=x*10+ch-'0';
        ch=gc();
    }
    return x*f;
}
using namespace std;
const int N=2e5+55;
const int inf=0x3f3f3f3f;
const int mod=998244353;
const double eps=1e-6;
const double PI=acos(-1);

int a[10][10],sum[10][10],f[20][10][10][10][10];

void dfs(int k,int x1,int y1,int x2,int y2)
{
    
    
    f[k][x1][y1][x2][y2]=inf;
    for(int i=x1;i<x2;i++)
    {
    
    
        f[k][x1][y1][x2][y2]=min(f[k][x1][y1][x2][y2],f[k-1][x1][y1][i][y2]+f[0][i+1][y1][x2][y2]);
        f[k][x1][y1][x2][y2]=min(f[k][x1][y1][x2][y2],f[0][x1][y1][i][y2]+f[k-1][i+1][y1][x2][y2]);
    }
    for(int i=y1;i<y2;i++)
    {
    
    
        f[k][x1][y1][x2][y2]=min(f[k][x1][y1][x2][y2],f[k-1][x1][y1][x2][i]+f[0][x1][i+1][x2][y2]);
        f[k][x1][y1][x2][y2]=min(f[k][x1][y1][x2][y2],f[0][x1][y1][x2][i]+f[k-1][x1][i+1][x2][y2]);
    }
}

void solve()
{
    
    
    int n;
    cin>>n;
    for(int i=1;i<=8;i++)
    {
    
    
        for(int j=1;j<=8;j++)
        {
    
    
            cin>>a[i][j];
            sum[i][j]=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1]+a[i][j];
        }
    }
    for(int i=1;i<=8;i++)
    {
    
    
        for(int j=1;j<=8;j++)
        {
    
    
            for(int p=i;p<=8;p++)
            {
    
    
                for(int q=j;q<=8;q++)
                {
    
    
                    int t=sum[p][q]-sum[p][j-1]-sum[i-1][q]+sum[i-1][j-1];
                    f[0][i][j][p][q]=t*t;
                }
            }
        }
    }
    for(int k=1;k<=n-1;k++)
        for(int i=1;i<=8;i++)
            for(int j=1;j<=8;j++)
                for(int p=i;p<=8;p++)
                    for(int q=j;q<=8;q++)
                        dfs(k,i,j,p,q);
    int tot=f[n-1][1][1][8][8];
    double avy=sum[8][8]*1.0/n;
    double ans=sqrt(1.0*tot/n-avy*avy);
    printf("%.3f\n",ans);
}

signed main()
{
    
    
    solve();


    return 0;
}

Guess you like

Origin blog.csdn.net/Joker_He/article/details/109881899