poj 3709 K-Anonymous Sequence

来源:互联网 发布:win10网络连接受限制 编辑:程序博客网 时间:2024/04/28 09:17

http://poj.org/problem?id=3709

第一道 斜率优化DP

优化前:

#include<stdio.h>#include<string.h>int T;int n,k;int num[500005];int s[500005];int f[500005];int que[500005],le=1,ri=0;int min(int a,int b){return a<b?a:b;}int main(){    scanf("%d",&T);    int t;    for(t=0;t<T;t++)    {        memset(f,0x3f,sizeof(f));        memset(que,0,sizeof(que));        le=1,ri=0;        scanf("%d%d",&n,&k);        int i,j;        for(i=1;i<=n;i++)        {            scanf("%d",&num[i]);            s[i]=s[i-1]+num[i];        }        for(i=1;i<k*2&&i<=n;i++) f[i]=s[i]-num[1]*i;        for(i=k*2;i<=n;i++)        {            for(j=k;j<=i-k;j++)            {                f[i]=min(f[j]+s[i]-s[j]-num[j+1]*(i-j),f[i]);            }        }        printf("%d\n",f[n]);    }    return 0;}

优化后:

#include<stdio.h>#include<string.h>long long T;long long n,k;long long num[500005];long long s[500005];long long f[500005];long long que[500005],le=1,ri=0;long long min(long long a,long long b){return a<b?a:b;}long long y(long long p){    return num[p+1]*p+f[p]-s[p];}int main(){    scanf("%lld",&T);    long long t;    for(t=0;t<T;t++)    {        memset(f,0x3f,sizeof(f));        memset(que,0,sizeof(que));        le=1,ri=0;        scanf("%lld%lld",&n,&k);        long long i,j;        for(i=1;i<=n;i++)        {            scanf("%lld",&num[i]);            s[i]=s[i-1]+num[i];        }        que[++ri]=k;        for(i=1;i<k*2&&i<=n;i++)f[i]=s[i]-num[1]*i;        for(i=k*2;i<=n;i++)        {            while(le<ri&&y(que[le+1])-y(que[le])<=i*(num[que[le+1]+1]-num[que[le]+1])) le++;            f[i]=y(que[le])-i*(num[que[le]+1])+s[i];            while(le<ri&&(y(que[ri])-y(que[ri-1]))*(num[i-k+2]-num[que[ri]+1])>=(y(i-k+1)-y(que[ri]))*(num[que[ri]+1]-num[que[ri-1]+1])) ri--;            que[++ri]=i-k+1;        }        printf("%lld\n",f[n]);    }    return 0;}
0 0