HDOJ 4628 - Pieces 状态压缩DP..枚举所有子集进行更新

    开始题目看错了....以为是连着的回文才能一次消掉..题目的意思是分开的也行...

    串最长16..很容易想到状态压缩DP....当本状态回文时..直接为1...否则是其两个相对其互补的子集并的最小值...更新的时候要枚举其所有的子集...

    比如说二进制状态t..要枚举其所有的子集..for(int i=t;i;i=(i-1)&t) 


Program:

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<cmath>
#include<queue>
#include<stack>
#include<set>
#include<algorithm>
#define ll long long
#define oo 1000000007
#define pi acos(-1.0)
#define MAXN 16
using namespace std;    
char s[MAXN];
int dp[1<<MAXN],n;
bool IsPalindrome(int x)
{
       char ss[MAXN];
       int i,j,m;
       m=0;
       for (i=0;i<n;i++)
          if (x & (1<<i))
             ss[m++]=s[i];
       i=0,j=m-1;
       while (i<=j && ss[i]==ss[j]) i++,j--;
       if (i>j) return true;
       return false;
}
int main()
{ 
       int T; 
       scanf("%d",&T);
       while (T--)
       {
                scanf("%s",s);
                n=strlen(s);
                dp[0]=0;
                for (int t=1;t<(1<<n);t++)
                {
                       dp[t]=oo;
                       if (IsPalindrome(t)) dp[t]=1; 
                       for(int i=t;i;i=(i-1)&t)  //枚举t的所有子集
                          dp[t]=min(dp[t],dp[i]+dp[t^i]);    
                }
                printf("%d\n",dp[(1<<n)-1]);
       }
       return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值