Description
有一行 N 个弹子,每一个都有一个颜色。每次可以让超过 K 个的连续的同颜色的一段弹子消失,剩下的会重新紧凑在一起。你有无限的所有颜色的弹子,要求在这行弹子中插入最少的弹子,使得弹子全部消失。
Input
The first line of input contains two integers N (1 ≤ N ≤ 100) and K (2 ≤ K ≤ 5) - the number of marbles in the initial sequence and the minimal number of consecutive marbles of the same color he could wish to vanish. The next line contains exactly N integers between 1 and 100 (inclusive), separated by one space. Those numbers represent colors of marbles in the sequence Mirko found.
Output
The output should contain only one line with a single integer number - the minimal number of marbles Mirko has to insert to achive the desired effect.
Sample Input
10 4
3 3 3 3 2 3 1 1 1 3
3 3 3 3 2 3 1 1 1 3
Sample Output
4
HINT
Source
Contest5
状压DP~
用f[i][j][kk]表示区间[i,j],i的左面添加kk个珠子的最小答案,那么
kk<k-1时,可以把i合并,f[i][j][kk]=min(f[i][j][kk],f[i][j][kk+1]+1);
kk==k-1时,f[i][j][kk]=min(f[i][j][kk],f[i+1][j][0]);
然后,如果f[l][r][kk]=min(f[l][r][kk],f[l+1][i-1][0]+f[i][r][kk+1])。
记忆化搜索比较好(写)
因为读入优化WA了一次2333
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;const int inf=99999999;int n,k,a[101],f[101][101][6];int read()
{int x=0,f=1;char ch=getchar();while(ch<'0' || ch>'9') {if(ch=='-') f=-1;ch=getchar();}while(ch>='0' && ch<='9') {x=x*10+ch-'0';ch=getchar();}return x*f;
}int find(int l,int r,int kk)
{if(l>r) return 0;if(f[l][r][kk]!=-1) return f[l][r][kk];f[l][r][kk]=inf;if(kk<k-1) f[l][r][kk]=min(f[l][r][kk],find(l,r,kk+1)+1);else if(kk==k-1) f[l][r][kk]=min(f[l][r][kk],find(l+1,r,0));for(int i=l+1;i<=r;i++)if(a[i]==a[l]) f[l][r][kk]=min(f[l][r][kk],find(l+1,i-1,0)+find(i,r,min(k-1,kk+1)));return f[l][r][kk];
}int main()
{n=read();k=read();for(int i=1;i<=n;i++) a[i]=read();memset(f,-1,sizeof(f));printf("%d\n",find(1,n,0));return 0;
}