第一问没有问题,就是第二问; 我设他f[i][j]代表最后一个区域长这样:i,i+1,i+2...,j
可得转移方程为
当i=j 就是新建一个区域,那就是结尾为j-1的最小值了
f[i][j]=f[1到i−1][j−1]的最大值+1
当i!=j 那就是继承从上一个,那就是从i开始j−1结束的,如果在i到j−1这个区间有新加入的这个数也就是a[j]那就为f[i−1][j−1],如果没有,那就是f[i−1][j−1+1]
#include<bits/stdc++.h>
using namespace std;
const int maxa=1e6;
int n,m,K,a[1010],f[1010][1010],qwq[30],ansa=1;
void ans1(){
int l=1;
for(int i=1;i<=n;i++){
int t=0;
for(int j=l;j<=i;j++){
if(qwq[a[j]]==0)t++;
qwq[a[j]]=1;
}
if(t>K){
l=i;
ansa++;
}
for(int k=1;k<=25;k++)qwq[k]=0;
}
cout<<ansa<<endl;
}
int main(){
cin>>n>>m>>K;
for(int i=1;i<=n;i++)
cin>>a[i];
ans1();
for(int i=1;i<=n;i++)
f[i][i]=INT_MAX;
f[1][1]=1;
for(int j=2;j<=n;j++){
for(int i=1;i<=j;i++){
if(i==j)
for(int k=1;k<=i-1;k++)
f[i][j]=min(f[i][j],f[k][j-1]+1);
else{
if(f[i][j-1]==maxa){
f[i][j]=f[i][j-1];
continue;
}
bool bb=true;
for(int k=i;k<=j-1;k++){
if(a[k]==a[j]){
f[i][j]=f[i][j-1];
bb=false;
break;
}
}
if(bb==false)continue;
f[i][j]=f[i][j-1]+1;
int t=0;
for(int k=i;k<=j;k++){
qwq[k]++;
if(qwq[k]==1)t++;
}
for(int k=1;k<=25;k++)qwq[k]=0;
if(t>K)f[i][j]=maxa;
}
}
}
int ans=INT_MAX;
// for(int i=1;i<=n;i++){
// for(int j=1;j<=n;j++){
// cout<<f[i][j]<<' ';
// }cout<<endl;
// }
for(int i=1;i<=n;i++)ans=min(ans,f[i][n]);
cout<<ans;
return 0;
}/*
10 4 3
1 2 3 4 3 4 3 2 1 2
*/
我感觉思路没问题,加了点减枝时间肯定够但WA了只有10分,大佬们帮帮我