您的位置:首页 > 其它

ZOJ3070 POJ2978 Colored stones,压缩状态DP

2012-06-06 21:00 197 查看
今晚和女友吵架,心情超不爽,我这个博客开了这么久,也许她也从来没有上来看过吧

/*******************************************************************************
# Author : Neo Fung
# Email : neosfung@gmail.com
# Last modified: 2012-06-06 20:56
# Filename: ZOJ3070 POJ2978 Colored stones.cpp
# Description :
******************************************************************************/
#ifdef _MSC_VER
#define DEBUG
#define _CRT_SECURE_NO_DEPRECATE
#endif

#include <fstream>
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <string>
#include <limits.h>
#include <algorithm>
#include <math.h>
#include <numeric>
#include <functional>
#include <ctype.h>
using namespace std;

const int kMAX=110;

// dp[x][y][z],x指的是到达第x个石子,包含第x个石子的情况下,颜色组合为y(每种颜色占一位),
// 最后一颗石子的颜色为z的最多剩余石子数,因为第x棵石子去留不一定,所以z不一定等于x的颜色
int dp[kMAX][1<<6][6];

int main(void)
{
#ifdef DEBUG
freopen("../stdin.txt","r",stdin);
freopen("../stdout.txt","w",stdout);
#endif

int n,m,tmp;
//   scanf("%d",&ncase);

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",&tmp);
--tmp;
for(int j=0;j<len;++j)
{
if(!(j&(1<<tmp))) // 如果第i颗石子的颜色从未使用
{
for(int k=0;k<m;++k)
{
dp[i][j|(1<<tmp)][tmp]=max(dp[i][j|(1<<tmp)][tmp],dp[i-1][j][k]+1);	// 使用这颗石子
dp[i][j][k]=max(dp[i][j][k],dp[i-1][j][k]);	// 不用这颗石子
}
}
else	// 如果第i颗石子的颜色已经用过
{
for(int k=0;k<m;++k)
if(k==tmp)
dp[i][j][k]=max(dp[i][j][k],dp[i-1][j][k]+1);	// 如果第i颗石子的颜色和在i前面剩余石子中的最后一颗石子颜色一样,则i必定留下来
else
dp[i][j][k]=max(dp[i][j][k],dp[i-1][j][k]);	// 否则就不留
}
}
}
int ans=0;
for(int k=0;k<m;++k)
for(int j=0;j<len;++j)
ans=max(ans,dp
[j][k]);
printf("%d\n",n-ans);
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: