HDU 4745 Two Rabbits

Posted jpphy0

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU 4745 Two Rabbits相关的知识,希望对你有一定的参考价值。

链接

Two Rabbits - http://acm.hdu.edu.cn/showproblem.php?pid=4745

分析

  • dp(i,j)定义:从区间[i, j]两端进入能跳跃的最大步数,跳入算1步,跳出不算
  • 区间转换策略:若区间[i,j]两端的值相同,则转移到区间[i+1,j-1],状态转移方程是dp[i,j]=max(dp[i,j],dp[i+1,j-1]+2);若区间[i,j]两端的值不相同,则转移到区间[i,j-1] 或 [i+1,j],状态转移方程是dp[i,j]=max(dp[i,j],max(dp[i+1,j],dp[i,j-1]));
  • 结果是回文:若起点是同一块石头1,则 ……32123;若起点不是同一块石头,则:123……(Tom向右), ……321(Jerry向左)。
  • 如果整体不是回文串,那么1)若起点是同一个位置,则可截断成两个回文串;2)若起点不是同一个位置,则亦可截断成两个回文串;如:
  • 1 3 2 <-Jerry1TOM-> 2 3 1 || 5 5 或 5 1 3 2 <-Jerry1TOM-> 2 3 1 5
  • 1 3 1 || 2 3 <-Jerry1 2 3 3 2 1TOM-> 3 2
  • 1 3 1 || 2 3 1TOM-> 2 3 3 2 <-Jerry1 3 2

代码

#include<bits/stdc++.h>
using namespace std;
#define MXN 1010
int N, a[MXN], dp[MXN][MXN];
int main(){
	int s, t, ans;
	while(cin >> N, N){		
		for(int i = 1; i <= N; i++) scanf("%d", a+i);
		memset(dp, 0, sizeof dp);
		//
		for(int i = 1; i <= N; i++) dp[i][i] = 1;
		for(int len = 2; len <= N; len++){ // 长度	
			for(int s = 1; s <= N-len+1; s++){ // 起点
				t = s+len-1; // 终点
				if(a[s] == a[t])
					dp[s][t] = max(dp[s][t], dp[s+1][t-1]+2);
				else
					dp[s][t] = max(dp[s][t],max(dp[s+1][t], dp[s][t-1]));				
			}
		}
		ans = 0;
		for(int i = 1; i <= N; i++) ans = max(ans, dp[1][i]+dp[i+1][N]);
		printf("%d\\n", ans);
	} 
	return 0;
}

以上是关于HDU 4745 Two Rabbits的主要内容,如果未能解决你的问题,请参考以下文章

HDU 4745---Two Rabbits(区间DP)

HDU 4745 Two Rabbits(最长回文子序列)

hdu-4745 Two Rabbits

CF1304A Two Rabbits

Two Rabbits_dp求最长不连续回文子序列

HDU 6170 Two strings 思维 DP