整体思路理解,写出了一份正确代码如下:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ls (k<<1)
#define rs (k<<1|1)
#define mid ((l+r)>>1)
const int INF = 0x3f3f3f3f,N = 35050;
inline ll read()
{
ll ret=0;char ch=' ',c=getchar();
while(!(c>='0'&&c<='9')) ch=c,c=getchar();
while(c>='0'&&c<='9') ret=(ret<<1)+(ret<<3)+c-'0',c=getchar();
return ch=='-'?-ret:ret;
}
int n,m,a[N];
int dp[55][N],maxn[N<<2],lazy[N<<2];
int lst[N],pre[N];
void build(int k,int l,int r,const int id)
{
lazy[k]=0;
if(l==r) {maxn[k]=dp[id][l-1];return;}
build(ls,l,mid,id);
build(rs,mid+1,r,id);
maxn[k]=max(maxn[ls],maxn[rs]);
}
inline void add(int k,int l,int r,int v)
{
maxn[k]+=v,lazy[k]+=v;
}
inline void pushdown(int k,int l,int r)
{
if(!lazy[k]) return;
add(ls,l,mid,lazy[k]);
add(rs,mid+1,r,lazy[k]);
lazy[k]=0;
}
void modify(int k,int l,int r,int x,int y,int v)
{
if(x<=l&&r<=y) {add(k,l,r,v);return;}
pushdown(k,l,r);
if(x<=mid) modify(ls,l,mid,x,y,v);
if(y>mid) modify(rs,mid+1,r,x,y,v);
maxn[k]=max(maxn[ls],maxn[rs]);
}
int query(int k,int l,int r,int x,int y)
{
if(x<=l&&r<=y) return maxn[k];
pushdown(k,l,r);
int ret=0;
if(x<=mid) ret=max(ret,query(ls,l,mid,x,y));
if(y>mid) ret=max(ret,query(rs,mid+1,r,x,y));
return ret;
}
int main()
{
n=read(),m=read();
for(int i=1;i<=n;i++)
{
a[i]=read();
lst[i]=pre[a[i]];
pre[a[i]]=i;
}
for(int i=1;i<=m;i++)
{
build(1,1,n,i-1);
for(int j=1;j<=n;j++)
{
modify(1,1,n,lst[j]+1,j,1);
dp[i][j]=query(1,1,n,1,j);
}
}
printf("%d\n",dp[m][n]);
return 0;
}
但是另一份代码只有一点细节的变化,我觉得也对,但是过不去样例2,如下(区别已经标注在代码里):
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ls (k<<1)
#define rs (k<<1|1)
#define mid ((l+r)>>1)
const int INF = 0x3f3f3f3f,N = 35050;
inline ll read()
{
ll ret=0;char ch=' ',c=getchar();
while(!(c>='0'&&c<='9')) ch=c,c=getchar();
while(c>='0'&&c<='9') ret=(ret<<1)+(ret<<3)+c-'0',c=getchar();
return ch=='-'?-ret:ret;
}
int n,m,a[N];
int dp[55][N],maxn[N<<2],lazy[N<<2];
int lst[N],pre[N];
void build(int k,int l,int r,const int id)
{
lazy[k]=0;
if(l==r) {maxn[k]=dp[id][l];return;}//区别 1
build(ls,l,mid,id);
build(rs,mid+1,r,id);
maxn[k]=max(maxn[ls],maxn[rs]);
}
inline void add(int k,int l,int r,int v)
{
maxn[k]+=v,lazy[k]+=v;
}
inline void pushdown(int k,int l,int r)
{
if(!lazy[k]) return;
add(ls,l,mid,lazy[k]);
add(rs,mid+1,r,lazy[k]);
lazy[k]=0;
}
void modify(int k,int l,int r,int x,int y,int v)
{
if(x<=l&&r<=y) {add(k,l,r,v);return;}
pushdown(k,l,r);
if(x<=mid) modify(ls,l,mid,x,y,v);
if(y>mid) modify(rs,mid+1,r,x,y,v);
maxn[k]=max(maxn[ls],maxn[rs]);
}
int query(int k,int l,int r,int x,int y)
{
if(x<=l&&r<=y) return maxn[k];
pushdown(k,l,r);
int ret=0;
if(x<=mid) ret=max(ret,query(ls,l,mid,x,y));
if(y>mid) ret=max(ret,query(rs,mid+1,r,x,y));
return ret;
}
int main()
{
n=read(),m=read();
for(int i=1;i<=n;i++)
{
a[i]=read();
lst[i]=pre[a[i]];
pre[a[i]]=i;
}
for(int i=1;i<=m;i++)
{
dp[i][1]=(i==1?1:0);//区别 2
build(1,1,n,i-1);
for(int j=2;j<=n;j++) //区别 3
{
modify(1,1,n,lst[j],j-1,1); //区别 4
dp[i][j]=query(1,1,n,1,j-1); //区别 5
//printf("dp[%d][%d]=%d\n",i,j,dp[i][j]);
//当前的dp[i][j]从dp[i-1][1~j-1]转移来
}
}
printf("%d\n",dp[m][n]);
return 0;
}
求助下面的代码为什么不对, 有做过的神帮忙解答吗?\kel