luoguP4072 [SDOI2016]征途

[SDOI2016]征途

大体

大概就是推推公式,发现很傻逼的\(n^3\)DP
get60
进一步我们发现状态不能入手,考虑优化转移
套个斜率优化板子
每一层转移来一次斜率优化

思路

先便便式子
\[s^2=m^{2}*\frac{\sum_{1}^{m}(a_{i}-\overline{a})^2}{m}\]
\[=m*\sum_{1}^{m}(a_{i}-\overline{a})^2\]
\[=m*\sum_{1}^{m}(a_{i}^2-2*a_{i}*\overline{a}+\overline{a}^2)\]
\[=m*\sum_{1}^{m}a_{i}^2-m*\sum_{1}^{m}2*a_{i}*\overline{a}+m*\sum_{1}^{m}\overline{a}^2\]
\[=m*\sum_{1}^{m}a_{i}^2-m*\sum_{1}^{m}2*a_{i}*\overline{a}+m*\sum_{1}^{m}\overline{a}^2\]
\[\overline{a}^2=\frac{\sum_{1}^{m}a_{i}}{m}\]
\[=m*\sum_{1}^{m}a_{i}^2-m*\sum_{1}^{m}2*a_{i}*\frac{\sum_{1}^{m}a_{i}}{m}+m*\sum_{1}^{m}(\frac{\sum_{1}^{m}a_{i}}{m})^2\]
额,多化简化简,就得到了,LaTeX太麻烦了,这里就不多打了
\[=m*\sum_{1}^{m}a_{i}^2-2*(\sum_{1}^{m}a_{i})^2+\sum_{1}^{m}\frac{(\sum_{1}^{m}a_{i})^2}{m}\]
\[=m*\sum_{1}^{m}a_{i}^2-2*(\sum_{1}^{m}a_{i})^2+(\sum_{1}^{m}a_{i})^2\]
\[=m*\sum_{1}^{m}a_{i}^2-(\sum_{1}^{m}a_{i})^2\]
注意:\(\sum_{1}^{m}a_{i}^2\)和\(2*(\sum_{1}^{m}a_{i})^2\)并不相同
然后我们发现\(2*(\sum_{1}^{m}a_{i})^2\)是个定值
我们只需要求\(\sum_{1}^{m}a_{i}^2\)这个最小就好了(m>0不用考虑)
然后我们可以\(f[i][j]\)表示选了\(i\)次,到了第\(j\)个点的最小和(入门dp,无脑状态)
状态转移方程:
\[f[i][j]=min(f[i][j],f[i-1][k]+(sum[j]-sum[k])*(sum[j]-sum[k]))\]
然后我们可以这个样纸

FOR(i,1,n) //选的第几次点
    FOR(j,1,n) //位置
        FOR(k,0,j) //由前面转移
            f[i][j]=min(f[i][j],f[i-1][k]+(sum[j]-sum[k])*(sum[j]-sum[k]));

我们发现状态是\(n^2\)个,每次转移是O(n)的,太墨迹了
那就套个斜率板子加个速,n次斜率转移
每一层都是由上一层转移,也可以滚动数组省内存一下,我看着128MB有点小

暴力60

/*
    此题推出式子来就好办了,n^3dp直接斜率优化成n^2
    次代码为本体暴力
*/
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const ll N=1e6+7;
ll read() {
    ll x=0,f=1;char s=getchar();
    for(;s>'9'||s<'0';s=getchar()) if(s=='-') f=-1;
    for(;s>='0'&&s<='9';s=getchar()) x=x*10+s-'0';
    return x*f;
}
ll n,m,sum[N];
ll f[3007][3007];
int main() {
    n=read(),m=read();
    for(int i=1;i<=n;++i) {
        int x=read();
        sum[i]=sum[i-1]+x;
    }
    memset(f,0x3f,sizeof(f));
    for(int i=0;i<=n;++i) f[1][i]=sum[i]*sum[i];
    for(int i=2;i<=m;++i) {
        f[i][0]=0;
        for(int j=1;j<=n;++j) {
            for(int k=0;k<=j;++k) {
                f[i][j]=min(f[i][j],f[i-1][k]+(sum[j]-sum[k])*(sum[j]-sum[k]));
            }
        }
    }
    cout<<m*f[m][n]-sum[n]*sum[n]<<"\n";
    return 0;
}

AC代码

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const ll N=3007;
ll read() {
    ll x=0,f=1;char s=getchar();
    for(;s>'9'||s<'0';s=getchar()) if(s=='-') f=-1;
    for(;s>='0'&&s<='9';s=getchar()) x=x*10+s-'0';
    return x*f;
}
ll n,m,sum[N],f[N][N],q[N];
double calc(ll j,ll k,ll x) {
    ll xx=sum[j];
    ll yy=f[x-1][j]+sum[j]*sum[j];
    ll xx_=sum[k];
    ll yy_=f[x-1][k]+sum[k]*sum[k];
    return (yy-yy_)/(2.0*(xx-xx_));
}
void work(int x) {
    int h=0,d=0;
    for(int i=1;i<=n;++i){
        while(h<d && calc(q[h],q[h+1],x) <= sum[i]) h++;
        f[x][i]=f[x-1][q[h]]+(sum[i]-sum[q[h]])*(sum[i]-sum[q[h]]);
        while(h<d && calc(q[d],q[d-1],x) >=  calc(q[d],i,x)) d--;
        q[++d]=i;
    }
}
int main() {
    n=read(),m=read();
    for(int i=1;i<=n;++i) {
        int x=read();
        sum[i]=sum[i-1]+x;
    }
    memset(f,0x3f,sizeof(f));
    for(int i=0;i<=n;++i) f[1][i]=sum[i]*sum[i];
    for(int i=2;i<=m;++i) {
        f[i][0]=0;
        work(i);
    }
    cout<<m*f[m][n]-sum[n]*sum[n]<<"\n";
    return 0;
}

wxy刷noi,而我等蒟蒻只能刷省选

原文地址:https://www.cnblogs.com/dsrdsr/p/10222751.html

时间: 2024-08-02 20:14:30

luoguP4072 [SDOI2016]征途的相关文章

bzoj-4518 4518: [Sdoi2016]征途(斜率优化dp)

题目链接: 4518: [Sdoi2016]征途 Description Pine开始了从S地到T地的征途. 从S地到T地的路可以划分成n段,相邻两段路的分界点设有休息站. Pine计划用m天到达T地.除第m天外,每一天晚上Pine都必须在休息站过夜.所以,一段路必须在同一天中走完. Pine希望每一天走的路长度尽可能相近,所以他希望每一天走的路的长度的方差尽可能小. 帮助Pine求出最小方差是多少. 设方差是v,可以证明,v×m^2是一个整数.为了避免精度误差,输出结果时输出v×m^2. In

【BZOJ4518】[Sdoi2016]征途 斜率优化

[BZOJ4518][Sdoi2016]征途 Description Pine开始了从S地到T地的征途. 从S地到T地的路可以划分成n段,相邻两段路的分界点设有休息站. Pine计划用m天到达T地.除第m天外,每一天晚上Pine都必须在休息站过夜.所以,一段路必须在同一天中走完. Pine希望每一天走的路长度尽可能相近,所以他希望每一天走的路的长度的方差尽可能小. 帮助Pine求出最小方差是多少. 设方差是v,可以证明,v×m^2是一个整数.为了避免精度误差,输出结果时输出v×m^2. Inpu

动态规划(决策单调优化):BZOJ 4518 [Sdoi2016]征途

4518: [Sdoi2016]征途 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 532  Solved: 337[Submit][Status][Discuss] Description Pine开始了从S地到T地的征途. 从S地到T地的路可以划分成n段,相邻两段路的分界点设有休息站. Pine计划用m天到达T地.除第m天外,每一天晚上Pine都必须在休息站过夜.所以,一段路必须在同一天中走完. Pine希望每一天走的路长度尽可能相近,所以他

[Sdoi2016]征途

4518: [Sdoi2016]征途 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 1125  Solved: 623[Submit][Status][Discuss] Description Pine开始了从S地到T地的征途. 从S地到T地的路可以划分成n段,相邻两段路的分界点设有休息站. Pine计划用m天到达T地.除第m天外,每一天晚上Pine都必须在休息站过夜.所以,一段路必须在同一天中走完. Pine希望每一天走的路长度尽可能相近,所以

bzoj4518[Sdoi2016]征途 斜率优化dp

4518: [Sdoi2016]征途 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 1657  Solved: 915[Submit][Status][Discuss] Description Pine开始了从S地到T地的征途. 从S地到T地的路可以划分成n段,相邻两段路的分界点设有休息站. Pine计划用m天到达T地.除第m天外,每一天晚上Pine都必须在休息站过夜.所以,一段路必须在同一天中走完. Pine希望每一天走的路长度尽可能相近,所以

【bzoj4518】[Sdoi2016]征途 斜率优化dp

原文地址:http://www.cnblogs.com/GXZlegend/p/6812435.html 题目描述 Pine开始了从S地到T地的征途. 从S地到T地的路可以划分成n段,相邻两段路的分界点设有休息站. Pine计划用m天到达T地.除第m天外,每一天晚上Pine都必须在休息站过夜.所以,一段路必须在同一天中走完. Pine希望每一天走的路长度尽可能相近,所以他希望每一天走的路的长度的方差尽可能小. 帮助Pine求出最小方差是多少. 设方差是v,可以证明,v×m^2是一个整数.为了避免

BZOJ4518: [Sdoi2016]征途(dp+斜率优化)

Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 1875  Solved: 1045[Submit][Status][Discuss] Description Pine开始了从S地到T地的征途. 从S地到T地的路可以划分成n段,相邻两段路的分界点设有休息站. Pine计划用m天到达T地.除第m天外,每一天晚上Pine都必须在休息站过夜.所以,一段路必须在同一天中走完. Pine希望每一天走的路长度尽可能相近,所以他希望每一天走的路的长度的方差尽可能

BZOJ4518:[SDOI2016]征途——题解

https://www.lydsy.com/JudgeOnline/problem.php?id=4518 https://www.luogu.org/problemnew/show/P4072 Pine开始了从S地到T地的征途. 从S地到T地的路可以划分成n段,相邻两段路的分界点设有休息站. Pine计划用m天到达T地.除第m天外,每一天晚上Pine都必须在休息站过夜.所以,一段路必须在同一天中走完. Pine希望每一天走的路长度尽可能相近,所以他希望每一天走的路的长度的方差尽可能小. 帮助P

[luogu4072][bzoj4518][SDOI2016]征途

题目分析 Pine开始了从S地到T地的征途. 从S地到T地的路可以划分成n段,相邻两段路的分界点设有休息站. Pine计划用m天到达T地.除第m天外,每一天晚上Pine都必须在休息站过夜.所以,一段路必须在同一天中走完. Pine希望每一天走的路长度尽可能相近,所以他希望每一天走的路的长度的方差尽可能小. 帮助Pine求出最小方差是多少. 分析 比较简单的斜率优化. \[f[i][j]=min(f[k][j-1]+m(sum[i]-sum[j])^3-s\times s_n(s_i-s_j))\