• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
KのMidGard
人是人的一场雨,你终将独自前行。
博客园    首页    新随笔    联系   管理    订阅  订阅

[POJ2978]ColoredStones

题目大意:有N≤100个石头排成一列,每个石头都有颜色编号≤5,求扔掉最少的石头,使得任意两个相同颜色的石头之间没有其他颜色的石头[多组数据]

题目大意:有N≤100个石头排成一列,每个石头都有颜色编号≤5,求扔掉最少的石头,使得任意两个相同颜色的石头之间没有其他颜色的石头[多组数据]

题解:很明显的状态压缩DP,但我一开始竟然想到搜索剪枝(扔掉该扔的以后一定成了几个颜色的排列=5!,加点优化应该能过)

DP[i][j][k] 前 i 个 最后留下的石子颜色为 j 用 k 记录颜色的出现情况

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
int n,m,ins[101],dp[101][6][32];
int main(){
freopen("DP.in","r",stdin);
freopen("DP.out","w",stdout);
int i,j,k,t,u,v,mm;
scanf("%d%d",&n,&m);
while(n){
mm=1<<m;
memset(dp,0,sizeof(dp));
for(i=1;i<=n;i++){
scanf("%d",&ins[i]);
ins[i]--;
}
for(i=1;i<=n;i++) dp[i][ins[i]][1<<ins[i]]=1;
for(i=1;i<n;i++) for(j=0;j<m;j++) for(k=0;k<mm;k++) if(dp[i][j][k]){
t=dp[i][j][k];
u=ins[i+1];
v=1<<u;
if(u==j) dp[i+1][j][k]=max(dp[i+1][j][k],t+1);
else if(k&v) dp[i+1][j][k]=max(dp[i+1][j][k],t);
else{
dp[i+1][j][k]=max(dp[i+1][j][k],t);
dp[i+1][u][k|v]=max(dp[i+1][u][k|v],t+1);
}
}
k=1;
for(i=0;i<m;i++) for(j=0;j<mm;j++) k=max(k,dp[n][i][j]);
printf("%d\n",(n-k));
scanf("%d%d",&n,&m);
}
return 0;
}



posted @ 2011-11-19 16:42  风行狩  阅读(238)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3