题目描述
译自 COCI 2010.03.06 T4「ZUMA」
Mirko 将 𝑁N 颗弹子排成一排,依次编号为 1…𝑁1…N。𝑖i 号弹子的颜色为 𝑐𝑖ci。他发现,如果他触摸 ≥𝐾≥K 颗连续的弹子,且这些弹子的颜色相同,魔法会使这些弹子消失;此后,这 𝐾K 颗弹子前面的弹子便与这 𝐾K 颗弹子后面的弹子相邻。
Mirko 家里有很多弹子,他想在这 𝑁N 颗弹子之间(也可以在开头的弹子前面或末尾的弹子后面)插入尽可能少的弹子,使得这 𝑁N 颗弹子+插入的所有弹子消失。
输入格式
第一行:𝑁,𝐾N,K。
第二行:𝑐1…𝑐𝑁c1…cN。
输出格式
一行,一个整数,表示他至少要插入几颗弹子。
样例 #1
样例输入 #1
2 5
1 1
Copy
样例输出 #1
3
Copy
样例 #2
样例输入 #2
5 3
2 2 3 2 2
Copy
样例输出 #2
2
Copy
样例 #3
样例输入 #3
10 4
3 3 3 3 2 3 1 1 1 3
Copy
样例输出 #3
4
Copy
提示
1≤𝑁≤100,1≤N≤100, 2≤𝐾≤5,2≤K≤5, 1≤𝑐𝑖≤1001≤ci≤100.
思路
见代码:
#include<bits/stdc++.h>
using namespace std;
int n,m,f[301][301][305],s[1411],c[3111],qq,qqq;
char rg,dd[3];
struct ll{
char zf;
int sz;
}tx[111];
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>c[i];
}
memset(f,0x3f,sizeof(f));
for(int i=1;i<=n;i++){
for(int j=0;j<m;j++){
f[i][i][j]=m-j-1;
}
}
for(int l=2;l<=n;l++){
for(int i=1;i<=n;i++){
int j=l+i-1;
for(int z=m-1;z>=0;z--){
if(z==m-1){
f[i][j][z]=min(f[i][j][z],f[i+1][j][0]);
}
else{
f[i][j][z]=min(f[i][j][z],f[i][j][z+1]+1);
}
if(c[i]==c[i+1]){
f[i][j][z]=min(f[i][j][z],f[i+1][j][min(z+1,m-1)]);
}
for(int k=i+1;k<j;k++){
if(c[i]==c[k+1]){
f[i][j][z]=min(f[i][j][z],f[i+1][k][0]+f[k+1][j][min(z+1,m-1)]);
}
}
}
}
}
cout<<f[1][n][0];
return 0;
}