PAT 1007最大子序列和 1045最长不下降子序列 1040最长回文子串

1007 Maximum Subsequence Sum

dp[i]记录以A[i]结尾的最大连续子序列和,s[i]记录该序列对应的起始位置。

状态转移方程:dp[i]=max(A[i],dp[i-1]+A[i])

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {
	
    public static void main(String[] args) throws IOException {
    	BufferedReader reader=new BufferedReader(new InputStreamReader(System.in));

    	int N=Integer.valueOf(reader.readLine());
    	int[] nums=new int[N],dp=new int[N],s=new int[N];
    	String[] line=reader.readLine().split(" ");
    	for(int i=0;i<line.length;i++) {
    		nums[i]=Integer.valueOf(line[i]);
    	}
    	//边界
    	dp[0]=nums[0];
    	int k=0;
    	for(int i=1;i<N;i++) {
    		//状态转移
    		if(nums[i]>dp[i-1]+nums[i]) {
    			//只有A[i]一个元素
    			dp[i]=nums[i];
    			s[i]=i;
    		}else {
    			//加在前一个序列尾部
    			dp[i]=dp[i-1]+nums[i];
    			s[i]=s[i-1];
    		}
    		//找出最大和
    		if(dp[k]<dp[i]) {
    			k=i;
    		}
    	}
    	if(dp[k]<0) {
    		System.out.format("0 %d %d",nums[0],nums[N-1]);
    	}else {
    		System.out.format("%d %d %d",dp[k],nums[s[k]],nums[k]);
    	}
    }
}

1045 Favorite Color Stripe

题目要求得到的子序列中颜色顺序按照eva喜欢的顺序排列,可以将eva喜欢的颜色按顺序映射为递增序列,不喜欢的颜色映射为-1,然后在接下来的输入序列中剔除这些颜色,则题目即可按照求解最长不下降子序列问题(LIS)来解决。

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;

public class Main {
	
    public static void main(String[] args) throws IOException {
    	BufferedReader reader=new BufferedReader(new InputStreamReader(System.in));

    	int N=Integer.valueOf(reader.readLine());
    	String[] line=reader.readLine().split(" ");
    	int M=Integer.valueOf(line[0]),x;
    	int[] favor=new int[N+1];//将喜欢的颜色序列映射为递增序列,不喜欢的为-1
    	Arrays.fill(favor, -1);//初始化为-1
    	for(int i=0;i<M;i++) {
    		x=Integer.valueOf(line[i+1]);
    		favor[x]=i;//映射
    	}
    	line=reader.readLine().split(" ");
    	int L=Integer.valueOf(line[0]),num=0;//num存放序列中喜欢的颜色数
    	int[] colors=new int[L],dp=new int[L];
    	for(int i=0;i<L;i++) {
    		x=Integer.valueOf(line[i+1]);
    		if(favor[x]>=0)//只存储喜欢的颜色
    			colors[num++]=favor[x];
    	}
    	//求解LIS问题
    	int len=-1;
    	for(int i=0;i<num;i++) {
    		dp[i]=1;//边界初始条件(只有自己一个元素)
    		for(int j=0;j<i;j++) {
    			if(colors[j]<=colors[i]) {//添加到元素j后
    				dp[i]=Math.max(dp[i], dp[j]+1);//状态转移
    			}
    		}
    		len=Math.max(len, dp[i]);
    	}
    	System.out.println(len);
    }
}

1040 Longest Symmetric String

求出给定字符串的最长回文子串的长度。

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {
	
    public static void main(String[] args) throws IOException {
    	BufferedReader reader=new BufferedReader(new InputStreamReader(System.in));

    	String str=reader.readLine();
    	int len=str.length(),ans=1;
    	boolean[][] dp=new boolean[len][len];//记录子串i~j是否回文
    	for(int i=len-1;i>=0;i--) {//从数组尾部开始计算
    		dp[i][i]=true;//边界
    		for(int j=i+1;j<len;j++) {
    			if(str.charAt(i)==str.charAt(j)&&(dp[i+1][j-1]||j==i+1)) {
    				dp[i][j]=true;//状态转移
    	    		ans=Math.max(j-i+1, ans);
    			}
    		}
    	}
    	System.out.println(ans);
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章