Codeforces 392E Deleting Substrin(区间dp)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces 392E Deleting Substrin(区间dp)相关的知识,希望对你有一定的参考价值。

题目大意:

? 给定vi,wi,每次可以在wi中选择一个子段[l,r]满足:
? |wi-wi+1|=1 (l<=i<r)
? 2wi-wi-1-wi+1>=0 (l<i<r)
? 选择后获得vr-l+1的收益并把这个子段删除,可以不删完,求最大收益。
? n<=400

Examples
input
3
0 0 3
1 2 1
output
3
input
6
1 4 5 6 7 1000
2 1 1 2 2 3
output
12

题解:
我们删除的区间是一个单峰上凸的区间。
用f[i][j]表示将i到j全部删完得到的最大代价,g[i][j]表示将i到j的区间删成w[i],w[i]+1,……,w[j]的最大收益,h[i][j]
表示将i到j的区间删成w[i],w[i]-1,……,w[j]的最大收益。
f[i][j]可以由f[i][k]+f[k+1][j]||g[i][k]+h[k][j]+v[2*w[k]-w[i]-w[j]+1]转移过来。
h[i][j]和g[i][j]怎么维护呢? 当w[k]==w[i+1]时g[i][j]<-f[i+1][k-1]+g[k][j],h[i][j]同理。
代码:
#include<cstdio>
#include<algorithm>
#define inf 1<<28
using namespace std;
template<class T>inline void read(T &x)
{
    x=0;int f=0;char ch=getchar();
    while(ch<0||ch>9)f|=(ch==-),ch=getchar();
    while(ch<=9&&ch>=0)x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
    x=f?-x:x;
    return;
}
int n,v[410],w[410],f[410][410],h[410][410],g[410][410],ans[410];
int main()
{
    read(n);
    for(int i=1;i<=n;i++)read(v[i]);
    for(int i=1;i<=n;i++)read(w[i]);
    for(int l=1;l<=n;l++)
    {
        for(int i=1;i+l-1<=n;i++)
        {
            int j=i+l-1;
            if(i==j){g[i][j]=h[i][j]=0;f[i][j]=v[1];continue;}
            g[i][j]=h[i][j]=-inf;
            for(int k=i+1;k<=j;k++)
            if(w[k]==w[i]+1)g[i][j]=max(g[i][j],f[i+1][k-1]+g[k][j]);
            else if(w[k]==w[i]-1)h[i][j]=max(h[i][j],f[i+1][k-1]+h[k][j]);
            f[i][j]=-inf;
            for(int k=i;k<j;k++)
            f[i][j]=max(f[i][j],f[i][k]+f[k+1][j]);
            for(int k=i;k<=j;k++)
            if(g[i][k]>-1<<20&&h[k][j]>-1<<20)f[i][j]=max(f[i][j],g[i][k]+h[k][j]+v[2*w[k]-w[i]-w[j]+1]);
        }
    }
    for(int i=1;i<=n;i++)
    {
        ans[i]=ans[i-1];
        for(int j=1;j<=i;j++)
        ans[i]=max(ans[i],ans[j-1]+f[j][i]);
    }
    printf("%d\n",ans[n]);
    return 0;
}

 



以上是关于Codeforces 392E Deleting Substrin(区间dp)的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces Round #726 (Div. 2) D. Deleting Divisors(博弈,思维)

博弈论:倒腾思维D. Deleting Divisors——Codeforces Round #726 (Div. 2)

博弈论:倒腾思维D. Deleting Divisors——Codeforces Round #726 (Div. 2)

524. Longest Word in Dictionary through Deleting

《转》openstack中删除虚拟主机,状态一直deleting

《转》openstack中删除虚拟主机,状态一直deleting