}
#Python版
#思路:最长会文字序列:== Str与reverse_Str的最长公共字序列
#注意:碰到了楼上Python解法同样的问题,没把循环过程放到name中,一直说是过90%
#然后超时,放进去就好了。猜一下:是不是给了程序入口能加快解析 # -*- coding:utf-8 -*-
import sys
def maxlcp(strs):
if strs==None or len(strs)==0:
return 0
lens = len(strs)
dp =[0] *lens
dp[0] = 1 if strs[0] == strs[lens-1] else 0
for i in range(lens):
pre = dp[0]
dp[0] = max(dp[0],1 if strs[i] == strs[lens-1] else 0)
for j in range(1,lens):
cur = dp[j]
dp[j] = max(dp[j],dp[j-1])
if strs[i] == strs[lens-1-j]:
dp[j] = max(dp[j],pre+1)
pre = cur
return dp[lens-1]
if __name__ == '__main__':
while True:
line = sys.stdin.readline().strip()
lens = len(line)
if not line:
break
maxLcp = maxlcp(line)
# print lens
# print maxLcp
print lens - maxLcp
include<iostream>
#include<string>
using namespace std;
const int MAX_LENGTH = 1002;
int dynamic[MAX_LENGTH][MAX_LENGTH];
int min_palindrome(string s)
{
if(s.length() <= 1)
return 0;
for(int i=0; i<s.length(); ++i)
{
dynamic[i][i] = 0;
}
for(int l=2; l<=s.length(); ++l)
{
for(int s_ind=0; s_ind<=s.length()-l; ++s_ind)
{
if(s[s_ind] == s[s_ind+l-1])
dynamic[s_ind][s_ind+l-1] = s_ind+1<=s_ind+l-2 ? dynamic[s_ind+1][s_ind+l-2] : 0;
else
dynamic[s_ind][s_ind+l-1] = 1 + min(dynamic[s_ind+1][s_ind+l-1], dynamic[s_ind][s_ind+l-2]);
}
}
return dynamic[0][s.length()-1];
}
int main()
{
string s;
while(cin >> s)
{
cout << min_palindrome(s) << endl;
}
} import sys
def min_palindrome(s):
if len(s) <= 1:
return 0
dynamic = [[0] * len(s)] * len(s)
for l in xrange(2, len(s)+1):
for s_ind in xrange(0, len(s)+1-l):
if s[s_ind] == s[s_ind + l-1]:
dynamic[s_ind][s_ind + l-1] = 0 if s_ind+1>s_ind + l-2 else dynamic[s_ind+1][s_ind + l-2]
else:
dynamic[s_ind][s_ind + l-1] = 1 + min(dynamic[s_ind+1][s_ind + l-1], dynamic[s_ind][s_ind + l-2])
return dynamic[0][len(s)-1]
for line in sys.stdin:
print min_palindrome(line.strip()) import java.util.Scanner;public class ConstructPlalindrome { public static void main(String[] args) { Scanner scan = new Scanner(System.in); while(scan.hasNext()) { String s = scan.nextLine(); System.out.println(s); int len = lenghOfLCS(s, new StringBuffer(s).reverse().toString()); System.out.println(s.length() - len); } scan.close(); } //动态规划求最长公共子序列的长度 public static int lenghOfLCS(String s1, String s2) { char[] ch1 = s1.toCharArray(); char[] ch2 = s2.toCharArray(); int n1 = s1.length(); int n2 = s2.length(); int[][] table = new int[n1][n2];//所有元素默认初始化为0 if(ch1[0] == ch2[0]) table[0][0] = 1; //单独计算s2与s1首字母之间的的LCS长度 for(int i = 1; i < n2; ++i) { if(ch1[0] == ch2[i]) table[0][i] = 1; else table[0][i] = table[0][i-1]; } //单独计算s1与s2首字母之间的LCS长度 for(int i = 1; i < n1; ++i) { if(ch2[0] == ch1[i]) table[i][0] = 1; else table[i][0] = table[i-1][0]; } //递推求解各个字符处的LCS for(int i = 1; i < n1; ++i) { for(int j = 1; j < n2; ++j) { if(ch1[i] == ch2[j]) { table[i][j] = table[i-1][j-1] + 1; }else table[i][j] = table[i-1][j] > table[i][j-1] ? table[i-1][j] : table[i][j-1]; } } return table[n1-1][n2-1]; } }
#include<iostream>
#include<math.h>
#include<string>
#include<algorithm>
using namespace std;
int solve(string str){
int n=str.size();
int *flag=new int[n*n];
for(int i=0;i<n*n;i++){
flag[i]=0;
}
for(int i=n-1;i>=0;i--){
flag[i*n+i]=1;
for(int j=i+1;j<n;j++){
if(str[i]==str[j])
flag[i*n+j]=flag[(i+1)*n+j-1]+2;
else
flag[i*n+j]=max(flag[(i+1)*n+j],flag[i*n+j-1]);
}
}
int res=n-flag[n-1];
return res;
}
int main(){
string s;
while(cin>>s){
cout<<solve(s)<<endl;
}
return 0;
}
#include<iostream>
#include<string>
using namespace std;
int main(){
string s1;
int max_len[1001][1001];
while(cin >> s1){
string s2(s1.rbegin(), s1.rend());
for(int i=0;i<=s1.length();i++)
for(int j=0;j<=s2.length();j++){
if(i==0 || j==0 )
max_len[i][j] = 0;
else if(s1[i-1] == s2[j-1])
max_len[i][j] = max_len[i-1][j-1] + 1;
else
max_len[i][j] = max(max_len[i-1][j] , max_len[i][j-1]);
}
cout << s1.length() - max_len[s1.length()][s2.length()] <<endl;
}
}
function Max(a,b){
return a>b?a:b;
}
function find (str1) {
var str2 = str1.split("");str2 = str2.reverse();str2 = str2.join("");
var max = 0;
var resArr = new Array(str1.length+1);
for(var i = 0;i<=str1.length+1;i++){ //初始化
resArr[i] = new Array(str2.length+1);
for(var j = 0;j<=str2.length+1;j++){
resArr[i][j] = 0;
}
}
for(var i = 0;i<=str1.length;i++){
for(var j = 0;j<=str2.length;j++){
if(i==0||j==0){
resArr[i][j] = 0;
}else{
if(str1[i-1] == str2[j-1]){
resArr[i][j] = resArr[i-1][j-1]+1;//前一次循环中数组元素保存的值加1
}else{
resArr[i][j] = Max(resArr[i-1][j],resArr[i][j-1]);//不用连续
}
}
if(max<resArr[i][j]){
max = resArr[i][j];//保存最大的数,也就是匹配最长的长度
}
}
}
//输出结果
if(max == 0){
return str1.length;
}else{
return str1.length-max;
}
}
function getCount(str){
var strArr = str.split("");
var strLen = 0;
for(var i=0;i<strArr.length;i++){
for(var j=strArr.length;j>=i;j--){
if(strArr[i]==strArr[j]){
var count = 1;
var temp_i = i,temp_j = j;
while(strArr[++temp_i]==strArr[--temp_j]){
if(temp_i<temp_j){//情况一
count++;
}else if(temp_i == temp_j){//情况二
count+=0.5;
}else{//防止死循环
break;
}
}
if(temp_j>temp_i){//情况三
count+=0.5;
}
if(count>strLen){
strLen = count;
}
}
}
}
return str.length-Math.floor(strLen*2);
}
import java.util.*;
public class Main{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
while(sc.hasNext()){
String str =sc.nextLine();
char[] strchar = str.toCharArray();
int length= strchar.length;
int[][] dp = new int[length][length];
for(int j=1;j<length;j++){
dp[j-1][j]=strchar[j-1]==strchar[j]?0:1;
for(int i=j-2;i>-1;i--){
if(strchar[i]==strchar[j]){
dp[i][j]=dp[i+1][j-1];
}else{
dp[i][j]=Math.min(dp[i+1][j],dp[i][j-1])+1;
}
}
}
}
}
}
import sys
def main():
for line in sys.stdin:
str1 = line[:-2]
n = len(str1)
str2 = str1[::-1]
rec = [[0 for x in range(n+1)] for x in range(n+1)]
for i in range(1,n+1):
for j in range(1,n+1):
if str1[j-1] == str2[i-1]:
rec[i][j] = rec[i-1][j-1] + 1
else:
rec[i][j] = max(rec[i-1][j], rec[i][j-1])
print n - rec[n][n]
main()
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
const int MAX = 1001;
int MaxLen[MAX][MAX]; //最长公共子序列,动态规划求法
int maxLen(string s1, string s2){
int length1 = s1.size();
int length2 = s2.size();
for (int i = 0; i < length1; ++i)
MaxLen[i][0] = 0;
for (int i = 0; i < length2; ++i)
MaxLen[0][i] = 0;
for (int i = 1; i <= length1; ++i)
{
for (int j = 1; j <= length2; ++j)
{
if (s1[i-1] == s2[j-1]){
MaxLen[i][j] = MaxLen[i-1][j - 1] + 1;
}
else
{
MaxLen[i][j] = max(MaxLen[i - 1][j], MaxLen[i][j - 1]);
}
}
}
return MaxLen[length1][length2];
}
int main(){
string s;
while (cin >> s){
int length = s.size();
if (length == 1){
cout << 1 << endl;
continue;
}
//利用回文串的特点
string s2 = s;
reverse(s2.begin(),s2.end());
int max_length = maxLen(s, s2);
cout << length - max_length << endl;
}
return 0;
}
#include <bits/stdc++.h>
using namespace std;
/*
dp[i][j]: i到j的最长回文子序列长度
1. s[i] = s[j], 则dp[i][j] = dp[i + 1][j - 1] + 2;
2. s[i] != s[j], dp[i][j] = max(dp[i][j - 1], dp[i + 1][j]);
边界: dp[i][i] = 1;
*/
int main() {
string s;
int dp[1003][1003];
while (cin >> s) {
int n = s.size();
for (int i = 0; i < n; ++i) dp[i][i] = 1;
for (int j = 1; j < n; ++j) {
for (int i = j - 1; i >= 0; --i) {
if (s[i] == s[j]) dp[i][j] = dp[i + 1][j - 1] + 2;
else dp[i][j] = max(dp[i][j - 1], dp[i + 1][j]);
}
}
cout << n - dp[0][n - 1] << endl;
}
return 0;
}
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String str1;
// 最长回文串的长度其实就是原串及其反转串的最长公共子串的长度(无需连续),原串长度减去这个长度就是要删除的字符数
while((str1 = br.readLine()) != null) {
String str2 = new StringBuilder(str1).reverse().toString();
int n = str1.length();
int[][] dp = new int[n + 1][n + 1];
for(int i = 1; i <= n; i++){
for(int j = 1; j <= n; j++)
dp[i][j] = str1.charAt(i - 1) == str2.charAt(j - 1)? dp[i - 1][j - 1] + 1: Math.max(dp[i - 1][j], dp[i][j - 1]);
}
System.out.println(n - dp[n][n]);
}
}
} public static int maxLen(String str) {
StringBuilder sb1 = new StringBuilder(str);
StringBuilder sb2 = new StringBuilder(str).reverse();
int len = str.length();
int[][] maxLen = new int[len + 1][len + 1];
for (int i = 1; i <= len; i++) {
for (int j = 1; j <= len; j++) {
if (sb1.charAt(i - 1) == sb2.charAt(j - 1))
maxLen[i][j] = maxLen[i - 1][j - 1] + 1;
else
maxLen[i][j] = Math.max(maxLen[i - 1][j], maxLen[i][j - 1]);
}
}
return len - maxLen[len][len];
} 开始用了递归,时间复杂度太高,改用了动态规划,通过。
/* 做题需要脑子,多分析思考。。
* 多思考,问题会很简单。。。。
* 数学分析。。。。。。。。。。
*/
#include<stdio.h>
char s[1000];
int a[1000][1000];
int min( int x, int y)
{
return x<y?x:y;
}
//递归时间复杂度太高了,改用动态规划
int func( int begin, int end)
{
int i, k;
for( k=1; k<end-begin+1; k++)
{
for( i=begin; i<end; i++)
{
if( s[i]==s[i+k]) a[i][i+k]=a[i+1][i+k-1];
else a[i][i+k] = min( a[i][i+k-1], a[i+1][i+k])+1;
}
}
return a[begin][end];
}
int main()
{
int i=0, j, flag=0; char c;
while(1)
{
for( i=0; (c=getchar())!=EOF; i++)
{
if( c=='\n') break;
s[i]=c;
}
if( c==EOF) break;
printf( "%d\n", func( 0, i-1));
}
return 0;
}
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
int solution(string s){
int result;
int n=s.length();
int dp[n][n];
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
dp[i][j]=0;
}
}
for(int j=0;j<n;j++){
dp[j][j]=1;
}
for(int j=1;j<n;j++){
for(int k=0;k<n-j;k++){
if(s[k]==s[k+j]){
dp[k][k+j]=dp[k+1][k+j-1]+2;
}
else{
dp[k][k+j]=max(dp[k+1][k+j],dp[k][k+j-1]);
}
}
}
result=n-dp[0][n-1];
return result;
}
int main(){
string s;
while(cin>>s){
cout<<solution(s)<<endl;
}
return 0;
}
int getGGZC(string s1,string s2){
vector<vector<int>> ss(s1.size(),vector<int>(s2.size(),0));
//初始化 如s1="abc" s2="acdeeee"。s1和s2首字母相等则
//ss[0][0](a,a),ss[0][1](a,ac),ss[0][2](a,acd)...
//ss[1][0](a,a),ss[2][0](ab,,a),ss[3][0](abc,a)...等最长公共子串都是1.
//首字母不等则都为0.
if(s1[0]==s2[0]){
for(int
i=0;i<s1.size();i++){
ss[i][0]=1;
}
for(int
j=0;j<s2.size();j++){
ss[0][j]=1;
}
}
//i,j分别表示s1和s2上字符的位置
//如 s1="abc"
s2="acdeeee" ss[1][2]的值就是“ab”和“acd”的最大公共子串长
for(int
i=1;i<s1.size();i++){
for(int j=1;j<s2.size();j++){
if(s1[i]==s2[j])ss[i][j]=ss[i-1][j-1]+1;
else{
ss[i][j]=max(ss[i-1][j],ss[i][j-1]);
}
}
}
int a=ss[s1.size()-1][s2.size()-1];
return a;
}
int main(){
string str;
while(cin>>str){
string ss=str;
reverse(ss.begin(),ss.end());
cout<<ss.size()-getGGZC(str,ss)<<endl;
}
return 0;
}
import java.util.*;
public class Main{
public static void main(String[] arg){
Scanner input = new Scanner(System.in);
while(input.hasNextLine()){
String s = input.nextLine();
char[] c = s.toCharArray();
intlen = c.length;
int[][] state = new int[len+1][len+1];
state[0][0] = 0;
for(int i = 0; i < len; i++){ //正序的每一个字符同反序的每一个字符比较
for(int j = 0; j < len; j++){
if(c[i] == c[len-1-j]) state[i+1][j+1] = state[i][j] + 1; //字符是相同的 则前一个字符相同的数加一
else state[i+1][j+1] = Math.max(state[i+1][j],state[i][j+1]); //对应的字符不相同 则取前面相同字符数中最大那个
//这样得到就是相同字符数最多的值 就是回文的长度 总长减去此长 就得到要删减的数目
}
}
System.out.println(len - state[len][len]);
}
}
}