POJ 8471 切割回文 【dp】【北大ACM/ICPC竞赛训练】

 1 #include<iostream>
 2 #include<vector>
 3 #define INF 100000
 4 using namespace std;
 5 
 6 string s;
 7 char a[1005];
 8 vector<int> hui[1005];//hui[i]里的k指 k到i组成回文
 9 int dp[1005];//dp[i]代表前i个字符要切几刀 
10 
11 int main(){
12     int t; cin>>t;
13     while(t--){
14         cin>>s;
15         int n = s.length();
16         for(int i=0;i<n;i++) a[i+1] = s[i];
17         for(int i=1;i<=n;i++) dp[i]=INF;
18         
19         hui[1].push_back(1);//第一个跟自己组成回文 
20         for(int i=2;i<=n;i++){
21             hui[i].push_back(i);//自己跟自己组成回文
22             if(a[i]==a[i-1]) hui[i].push_back(i-1);
23             for(int j=0;j<hui[i-1].size();j++){//看i的上一个字符,能与哪些字符组成回文 
24                 int k = hui[i-1][j];
25                 if( a[k-1]==a[i] ) hui[i].push_back(k-1);
26             }
27         }
28         
29         dp[0]=-1;
30         dp[1]=0;
31         for(int i=2;i<=n;i++){
32             for(int j=0;j<hui[i].size();j++) dp[i] = min(dp[i], dp[ hui[i][j]-1 ]+1 );
33         }
34         
35         cout<<dp[n]<<endl;
36         for(int i=1;i<=n;i++) hui[i].clear(); 
37     }
38 
39     return 0;    
40 }

猜你喜欢

转载自www.cnblogs.com/ZhenghangHu/p/9386435.html