首页 > 代码库 > Bzoj1939 [Croatian2010] Zuma
Bzoj1939 [Croatian2010] Zuma
Submit: 43 Solved: 31
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
参考了这里的题解 http://blog.csdn.net/u014609452/article/details/63267943
K的限制不定,当K>3的时候,似乎不能见一段消一段了(可能三段拼起来比消两段更优),好像不太容易区间DP?
大力脑洞一下发现还是可以DP的
$ f[i][j][k] $表示现在要消除 i ~ j 区间,在i的左边添加了k个珠子。
共有三种决策(@游戏王v6):
当k<K-1的时候,我们可以再加一个,也就是 $ f[i][j][k]=min(f[i][j][k],f[i][j][k+1]+1)$
当k=K-1的时候,可以消掉i,也就是 $ f[i][j][k]=f[i+1][j][0]$
当i和i+1位置的颜色相同的时候,我们可以把i看做合并到i+1,也就是 $ f[i][j][k] = f[i+1][j][k+1] $
转移有些零散,写成记忆化搜索的形式会很方便。
1 #include<iostream> 2 #include<algorithm> 3 #include<cstring> 4 #include<cstdio> 5 #include<cmath> 6 using namespace std; 7 const int mxn=105; 8 int read(){ 9 int x=0,f=1;char ch=getchar();10 while(ch<‘0‘ || ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();}11 while(ch>=‘0‘ && ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();}12 return x*f;13 }14 int n,K;15 int a[mxn];16 int f[mxn][mxn][mxn];17 int solve(int l,int r,int X){18 if(l>r)return 0;19 if(f[l][r][X]!=-1)return f[l][r][X];20 int &res=f[l][r][X]=0x3f3f3f3f;21 if(X<K-1)res=min(res,solve(l,r,X+1)+1);22 if(X==K-1)res=solve(l+1,r,0);23 for(int i=l+1;i<=r;i++)24 if(a[i]==a[l])25 res=min(res,solve(l+1,i-1,0)+solve(i,r,min(K-1,X+1)));26 return res;27 }28 int main(){29 int i,j;30 n=read();K=read();31 for(i=1;i<=n;i++)a[i]=read();32 memset(f,-1,sizeof f);33 solve(1,n,0);34 printf("%d\n",f[1][n][0]);35 return 0;36 }
Bzoj1939 [Croatian2010] Zuma
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。