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);
    }
}

 

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