ZOJ3070-The Colored Stones - 状态压缩dp

来源:互联网 发布:搞笑词语网络流行语言 编辑:程序博客网 时间:2024/06/17 20:22

题目大意:给你一段长为n的序列,每个石头都有一个颜色,一共有m中颜色,你可以每次拿走一块石头,最后这段序列没有一个颜色的石头会被另一个不同颜色的石头隔开,问你最少需要移走多少个石头;

题目解析:最后的序列每种颜色的石头肯定都挤在一起,每次我们加一个石头的时候就需要考虑前面有没有这种颜色的石头,而不需要知道有多少个,所以我们就可以想到用状态压缩;

dp[i][j][k]表示对第i块石头,颜色状态为j,最后一块石头颜色为k的最大序列长度;

代码:

#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>#include<string>using namespace std;int main(){int n,m,dp[110][1<<6][6],x,i,j,k,stone;while(scanf("%d%d",&n,&m)&&(n+m)){memset(dp,0,sizeof(dp));int len = 1<<m;for(int i=1;i<=n;i++){scanf("%d",&x);x--;for(j=0;j<len;j++){if(!(j&(1<<x))){for(k=0;k<m;k++){dp[i][j|(1<<x)][x]=max(dp[i][j|(1<<x)][x],dp[i-1][j][k]+1);dp[i][j][k]=max(dp[i][j][k],dp[i-1][j][k]);}}else {for(k=0;k<m;k++){if(k==x){dp[i][j][k]=max(dp[i][j][k],dp[i-1][j][k]+1);}else {dp[i][j][k]=max(dp[i][j][k],dp[i-1][j][k]);}}}}}stone=0;for(k=0;k<m;k++)for(j=0;j<len;j++)stone=max(stone,dp[n][j][k]);printf("%d\n",n-stone);}return 0;}


0 0