dp题2

1.seq

给出数组 A,则 l 到 r 的一段序列可以选择以下两种得分方式之一进行得分:1.得到𝐴𝑟-𝐴𝑙−1的分数,规定𝐴0
=02.把序列分为长度不小于 1 的两个子序列,得分为两个子序列的最大得分的乘积模 P现在请你求出长度为 n 的序列的最大得分是

#include<bits/stdc++.h>
#define rep(i,x,y) for(register LL i=x;i<=y;i++)
#define LL long long 
using namespace std;
const LL N=500;

LL n,p,a[N],f[N][N];

inline LL read(){
    LL x=0,f=1;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    while(isdigit(ch)){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
    return x*f;}
int main(){
    freopen("seq.in","r",stdin);
    freopen("seq.out","w",stdout);
    n=read(),p=read();
    rep(i,1,n) a[i]=read();
    rep(i,1,n) f[i][i]=a[i]-a[i-1];
    rep(len,2,n)
    rep(i,1,n-len+1){
        LL j=i+len-1;
        f[i][j]=max(f[i][j],a[j]-a[i-1]);
        rep(mid,i,j-1)
        f[i][j]=max(f[i][j],(f[i][mid]*f[mid+1][j])%p);}
    printf("%d",f[1][n]);return 0;
} 

2.最大全0子矩阵

#include<bits/stdc++.h>

using namespace std;

const int N=2050;
int n,ans;
int g[N][N],h[N][N];
int q[N],l[N],r[N];

int main()
{
    freopen("square.in","r",stdin);
    freopen("square.out","w",stdout);
    int n;scanf("%d",&n);
    
    for(int i=1;i<=n;i++)
    for(int j=1;j<=n;j++){
        scanf("%d",&g[i][j]);
        h[i][j]=g[i][j]?0:h[i-1][j]+1;
    }
    
    for(int i=1;i<=n;i++)
    {
        for(int j=1,top=0;j<=n;j++)
        {
            while(top&&h[i][q[top]]>=h[i][j]) --top;
            l[j]=top?q[top]+1:1;q[++top]=j;
        }
        for(int j=n,top=0;j>=1;j--)
        {
            while(top&&h[i][q[top]]>=h[i][j]) --top;
            r[j]=top?q[top]-1:n;q[++top]=j;
        }
        for(int j=1;j<=n;j++) ans=max(ans,(r[j]-l[j]+1)*h[i][j]);
    }
    printf("%d\n",ans);return 0;
}

单调栈

3.

 

posted @ 2018-09-21 08:38  ASDIC减除  阅读(167)  评论(0编辑  收藏  举报