鉴于他的字符串,每一个都能够删除回文子串。子可以是不连续,因此,像更好的模拟压力。求删除整个字符串需要的步骤的最小数量。
最大长度为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; }
版权声明:本文博主原创文章,博客,未经同意不得转载。
时间: 2024-11-06 07:15:27