[2017纪中10-21]Dark DP

来源:互联网 发布:unity3d角色动画模型 编辑:程序博客网 时间:2024/06/06 16:37

题目链接:https://jzoj.net/senior/#main/show/5408
发现sigma(Ai)很小,于是想到一个复杂度为O(sigma(Ai))。
f[i][j][0/1]表示填了前i个数,第i个数为j,前一个数是0/不是0的最小操作数,(第i个数可以不满足条件,因为之后的数还可以消它)。
于是转移:f[i][j][0]=min{f[i-1][Ai-j][0/1]}+a[i]-j;f[i][j][1]=min{f[i-1][k][0]}+a[i]-j (k>a[i]-j)。
因为最后一个式子涉及到后缀最小值,于是记一个mi[i][j]表示min{f[i][k]}(k>=j)即可。
代码:

#include<iostream>#include<cstdio>#define ll long long using namespace std;const int maxn=100010;int n,a[maxn];ll f[2][1000010][2],mi[2][1000010];int main(){    scanf("%d",&n);    for(int i=1;i<=n;i++)        scanf("%d",&a[i]);    for(int i=0;i<=1000001;i++)        mi[0][i]=f[0][i][0]=f[0][i][1]=1e9;    f[0][0][0]=mi[0][0]=0;          for(int i=1;i<=n;i++)    {        mi[i&1][a[i]+1]=1e9;        for(int j=a[i];j>=0;j--)        {            f[i&1][j][0]=f[i&1][j][1]=1e9;            if(a[i]-j<=a[i-1])f[i&1][j][0]=min(f[(i-1)&1][a[i]-j][0],f[(i-1)&1][a[i]-j][1])+a[i]-j;            if(a[i]-j+1<=a[i-1])  f[i&1][j][1]=mi[(i-1)&1][a[i]-j+1]+a[i]-j;            mi[i&1][j]=min(mi[i&1][j+1],f[i&1][j][0]);        }    }    printf("%lld",min(mi[n&1][0],f[n&1][0][1]));        return 0;}

还有一种与sigma(Ai)无关的QYQ的神做法。。。
还有一种与sigma(Ai)无关的QYQ的神做法。。。

原创粉丝点击