Significado de las preguntas:
Slastyona abrió una tienda de la torta, se encontró con la caja de pastel se puede poner en más rentable y una caja llena con el tipo de pastel, se puede vender más caro. Con sujeción a lo dispuesto en el valor de un cuadro que ha sido equipado tipo de pastel. Ella tiene que dejar que las cajas k fueron cargados en el pastel de hoy, y de caja que no puede estar vacío. pastel relleno debe ser tomada de un rango continuo. Slastyona quiere maximizar el valor total de toda la caja del pastel. Ayudar a determinar el valor máximo posible.
Formato de entrada: La primera línea contiene dos números enteros positivos n, el número k, que representan el número y la caja de la torta. La segunda línea contiene entero positivo n, la i-ésima categoría representa el i-ésimo torta
Los formatos de salida: un número entero positivo que representa el valor total de la caja.
Rango: n∈ garantizado [1,35000] y es un número entero, k∈ [1, min (n, 50)] y es un número entero. Para asegurarse de que el número total de tipos de torta in [1, n] y es un número entero.
\ (F_ {i, j} \) representa el delantero \ (I \) el número de dividido \ (J \) generada por el valor máximo actual
Claramente entonces una gama de dp, \ (col_ {I, J} \) representa \ ([i, j] \ ) en un número de diferentes tipos de
Así que al parecer esto es \ (O (kn ^ 2) \) , y podría no pase
Podemos considerar el uso de la optimización de la línea de árboles, probablemente pensando que puede causar un pastel a la gama es una contribución y es el mismo tipo de su posición 1 de este rango, entonces se puede utilizar la optimización de la línea de árboles
Este valle puede ir a la solución de Los Gangster a un problema, que es más revelador
// This code Write By chtholly_micromaker(MicroMaker)
#include <cstdio>
#include <cctype>
#include <iostream>
#include <cstring>
#define reg register
using namespace std;
const int MaxN=35005;
const int MaxK=55;
struct Node
{
int val,lazy;
};
template <class t> inline void rd(t &s)
{
s=0;
reg char c=getchar();
while(!isdigit(c))
c=getchar();
while(isdigit(c))
s=(s<<3)+(s<<1)+(c^48),c=getchar();
return;
}
int pre[MaxN],pos[MaxN];
int f[MaxK][MaxN];
struct SegTree
{
#define rt (u>>1)
#define lson (u<<1)
#define rson (u<<1|1)
Node tr[MaxN<<2];
inline void clear()
{
memset(tr,0,sizeof tr);
return;
}
inline void pushup(int u)
{
tr[u].val=max(tr[lson].val,tr[rson].val);
return;
}
inline void pushdown(int u,int l,int r)
{
if(tr[u].lazy)
{
tr[lson].lazy+=tr[u].lazy;
tr[rson].lazy+=tr[u].lazy;
tr[lson].val+=tr[u].lazy;
tr[rson].val+=tr[u].lazy;
tr[u].lazy=0;
}
return;
}
inline void buildtr(int u,int l,int r,int x)
{
if(l==r)
{
tr[u].val=f[x][l-1];
return;
}
reg int mid=(l+r)>>1;
buildtr(lson,l,mid,x);
buildtr(rson,mid+1,r,x);
pushup(u);
return;
}
inline void change(int u,int l,int r,int ql,int qr,int x)
{
if(ql<=l&&r<=qr)
{
tr[u].val+=x;
tr[u].lazy+=x;
return;
}
pushdown(u,l,r);
reg int mid=(l+r)>>1;
if(ql<=mid)
change(lson,l,mid,ql,qr,x);
if(mid<qr)
change(rson,mid+1,r,ql,qr,x);
pushup(u);
return;
}
inline int query(int u,int l,int r,int ql,int qr)
{
if(ql<=l&&r<=qr)
return tr[u].val;
pushdown(u,l,r);
reg int mid=(l+r)>>1,res=0;
if(ql<=mid)
res=max(res,query(lson,l,mid,ql,qr));
if(mid<qr)
res=max(res,query(rson,mid+1,r,ql,qr));
return res;
}
#undef rt
#undef lson
#undef rson
}segtr;
signed main(void)
{
int n,k;
reg int x;
rd(n);rd(k);
for(int i=1;i<=n;++i)
{
rd(x);
pre[i]=pos[x]+1;
pos[x]=i;
}
for(int i=1;i<=k;++i)
{
segtr.clear();
segtr.buildtr(1,1,n,i-1);
for(int j=1;j<=n;++j)
{
segtr.change(1,1,n,pre[j],j,1);
f[i][j]=segtr.query(1,1,n,1,j);
}
}
printf("%d\n",f[k][n]);
return 0;
}