您的位置:首页 > 其它

ZOJ3070-The Colored Stones - 状态压缩dp

2016-09-23 20:41 573 查看
题目大意:给你一段长为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
[j][k]);
printf("%d\n",n-stone);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  状态压缩 dp