首页 > 代码库 > HDU-4628 Pieces 状压DP
HDU-4628 Pieces 状压DP
给出一行字符串,每次可以删去一个回文子串,子串可以是不连续的,因此用状压比较好模拟,求删掉整个字符串需要的最少步数。
字符串的最大长度为16,因此不能逐行枚举状态,首先预处理出来所有的的回文子串,然后从第一步开始,依次状压第i步能到达的状态,如果能达到母串,跳出。
还有初始化不要用图省事用memset。。不优越的姿势+函数导致T了数发。
#include <iostream> #include <cstdio> #include <cstring> #include <queue> #include <cmath> #include <iomanip> #include <vector> #include <algorithm> using namespace std; char s[20]; char s1[20]; int ans; int num; int dp[1<<17][17]; int visit[20]; int Pow[15]; int a[1<<17]; bool solve(char str[]) { int flag=1; int start=0; int end=strlen(str)-1; while(start<=end) { if(str[start]!=str[end]) { flag=0; break; } start++; end--; } if(flag) { return true; } else { return false; } } int main() { int t; int sum; Pow[0]=1; for(int i=1;i<=18;i++) { Pow[i]=Pow[i-1]*2; } scanf("%d",&t); while(t--) { num=0; scanf("%s",s); int len=strlen(s); int mos=1<<(len); for(int i=1;i<=len;i++) { for(int j=1;j<mos;j++) { dp[j][i]=-1; } } int len1; s1[0] = '\0'; len1=0; int p; for(int i=1;i<mos;i++) { s1[0] = '\0'; len1=0; for(int j=0;j<len;j++) { if(i&Pow[j]) { s1[len1++]=s[j]; } } s1[len1]='\0'; //cout<<s1<<endl; if(solve(s1)) { a[num++]=i; } } for(int i=1;i<=17;i++) { for(int j=0;j<num;j++) { if(i==1) { dp[a[j]][i]=1; } else { for(int k=1;k<mos;k++) { if(dp[k][i-1]!=-1) { if(a[j]&k) { continue; } dp[(k|a[j])][i]=1; } } } } if(dp[mos-1][i]!=-1) { ans=i; break; } } printf("%d\n",ans); } return 0; }
HDU-4628 Pieces 状压DP
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。