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.