N - Pieces (状态dp)
2017-12-09 22:22
204 查看
You heart broke into pieces.My string broke into pieces.But you will recover one day,and my string will never go back.
Given a string s.We can erase a subsequence of it if this subsequence is palindrome in one step. We should take as few steps as possible to erase the whole sequence.How many steps do we need?
For example, we can erase abcba from axbyczbea and get xyze in one step.
InputThe first line contains integer T,denote the number of the test cases. Then T lines follows,each line contains the string s (1<= length of s <= 16).
T<=10.
OutputFor each test cases,print the answer in a line.
Sample Input
Sample Output
题意:
给一个字符串,长度<=16,每次去掉一个回文串,可以中不连续的,问最少用多少次把所给的串都去掉。
思路:
状态dp,分别用0和1表示原来字符串某个位置字符串是否去掉。0对应的是去掉的,1对应的是保留的。
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
char s[25];
int dp[1<<17];
int len;
int sta;
int init(int x){ //判断某个状态对应的字符串的回文串的大小,如果字符串全部回文,返回1,否则返回字符串的长度
int ss[17]={0};
int ans=0;
for(int i=0;i<=len;i++)
if(x&(1<<i))
ss[ans++]=i;
ans--;
for(int j=0;j<ans/2;j++) //从中点向两边看,是否回文,如果发现不回文的任意两个个字母,就返回状态x的字符串长度
if(s[ss[j]]!=s[ss[ans-j]])
return ans;
return 1;
}
void solve(){
len=strlen(s);
sta=1<<len;//初始的状态是11111……111,就是全部都存在
sta--;
for(int i=1;i<=sta;i++){ //枚举各种状态,对其进行初始化
dp[i]=init(i);//对每一个dp初始化
for(int k=i;k>0;k=(k-1)&i) //枚举每一个状态的子状态
dp[i]=min(dp[i],dp[k]+dp[k^i]);//子状态及其补集
}
}
int main(){
int T;
cin>>T;
while(T--){
memset(dp,0,sizeof(dp));
cin>>s;
solve();
cout<<dp[sta]<<endl;
}
return 0;
}
Given a string s.We can erase a subsequence of it if this subsequence is palindrome in one step. We should take as few steps as possible to erase the whole sequence.How many steps do we need?
For example, we can erase abcba from axbyczbea and get xyze in one step.
InputThe first line contains integer T,denote the number of the test cases. Then T lines follows,each line contains the string s (1<= length of s <= 16).
T<=10.
OutputFor each test cases,print the answer in a line.
Sample Input
2 aa abb
Sample Output
1 2
题意:
给一个字符串,长度<=16,每次去掉一个回文串,可以中不连续的,问最少用多少次把所给的串都去掉。
思路:
状态dp,分别用0和1表示原来字符串某个位置字符串是否去掉。0对应的是去掉的,1对应的是保留的。
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
char s[25];
int dp[1<<17];
int len;
int sta;
int init(int x){ //判断某个状态对应的字符串的回文串的大小,如果字符串全部回文,返回1,否则返回字符串的长度
int ss[17]={0};
int ans=0;
for(int i=0;i<=len;i++)
if(x&(1<<i))
ss[ans++]=i;
ans--;
for(int j=0;j<ans/2;j++) //从中点向两边看,是否回文,如果发现不回文的任意两个个字母,就返回状态x的字符串长度
if(s[ss[j]]!=s[ss[ans-j]])
return ans;
return 1;
}
void solve(){
len=strlen(s);
sta=1<<len;//初始的状态是11111……111,就是全部都存在
sta--;
for(int i=1;i<=sta;i++){ //枚举各种状态,对其进行初始化
dp[i]=init(i);//对每一个dp初始化
for(int k=i;k>0;k=(k-1)&i) //枚举每一个状态的子状态
dp[i]=min(dp[i],dp[k]+dp[k^i]);//子状态及其补集
}
}
int main(){
int T;
cin>>T;
while(T--){
memset(dp,0,sizeof(dp));
cin>>s;
solve();
cout<<dp[sta]<<endl;
}
return 0;
}
相关文章推荐
- hdu 4628 Pieces (状态压缩dp)
- HDOJ 4628 - Pieces 状态压缩DP..枚举所有子集进行更新
- hdu 4628 Pieces(状态压缩DP)
- hdu - 4628 - Pieces(状态压缩dp)
- HDU 4628 Pieces(状态压缩DP)
- Pieces (状态dp)
- HDU 4628 Pieces(状态压缩dp)
- HDU 4628 Pieces(DP + 状态压缩)
- hdu 4628 Pieces 状态压缩DP
- hdu 4614 pieces 状态DP
- hdu 4628 Pieces (状态压缩+二进制枚举+dp)
- hdu 4628 Pieces 状态压缩DP
- hdu 4628 Pieces (状态压缩dp)
- [hdu4628 Pieces]二进制子状态,DP
- hdu 4628 Pieces(状态压缩+DP,4级)
- 2013多校第三场 --Pieces--状态压缩DP
- POJ2184 Cow Exhibition[DP 状态负值]
- POJ - 1185 炮兵阵地 状态压缩DP
- 【状态压缩DP】[APIO2007]动物园
- 状压dp 处理有相邻顺序的或者有序的状态压缩问题