HDU 4745-2匹のウサギ(最長の非連続回文、間隔DP)

トピックリンク:

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

2匹のウサギ

制限時間:10000/5000 MS(Java /その他)メモリ制限:65535/65535 K(Java /その他)
合計送信数:1767受け入れられた送信数:914


問題の説明
ずっと昔、森の中にトムとジェリーの2匹のウサギが住んでいました。晴れた日の午後、彼らはいくつかの石でゲームをすることを計画しました。地面にはn個の石があり、時計回りのリングとして配置されていました。つまり、最初の石は2番目の石とn番目の石に隣接し、2番目の石は1番目の石と3番目の石に隣接します。i番目の石の重さはaiです。

ウサギはある石から別の石へとジャンプしました。トムは常に時計回りにジャンプし、ジェリーは常に反時計回りにジャンプしました。

最初は、ウサギは石を選んでその上に立っています。次に、各ターンで、トムは自分で踏んでいない石を選択してジャンプする必要があります。ジェリーはトムと同じことを行う必要がありますが、ジャンプの方向は反時計回りです。

なんらかの理由で、いつでも、2匹のウサギが立っていた2つの石の重さは等しくなければなりません。その上、どんなウサギもそれ自身で踏まれた石を飛び越えることができませんでした。言い換えれば、トムが2番目の石の上に立っていた場合、1番目の石から3番目の石に、またはn番目の石から4番目の石にジャンプすることはできません。

プロセス全体を通して、2匹のウサギが同じ石の上に同時に立っていても問題がなかったことに注意してください。 

今、彼らは最適な戦略に従った場合にプレイできる最大ターン数を知りたいと思っています。
 

入力
入力には、最大20のテストケースが含まれます。
各テストケースの最初の行には、石の数を示す整数nが含まれています。
次の行には、スペースで区切られたn個の整数が含まれ、i番目の整数aiはi番目の石の重量を示します。(1 <= n <= 1000、1 <= ai <= 1000)
入力はn =で終了します。 0。
 

出力
テストケースごとに、最大回転数を示す整数を出力します。
 

サンプル入力
  
   
   
1 1 4 1 1 2 1 6 2 1 1 2 1 3 0
 

サンプル出力
  
   
   
1 4 5


//区间DP, 转换成求最长非连续的回文串
//将数组扩大为2倍,计算每个区间的最长非连续的回文串
//状态转移方程dp[i][j] = max(dp[i][j], dp[i+1][j], dp[i][j-1], a[i]==a[j]?a[i+1][j-1]+2:0)
//注意像字符串1221,计算出来的dp[0][3] = 4,而不是2
//所以最后结果肯定是只有n个字符,或者n-1的字符加个1
#include <stdio.h>
#include <string.h>
#include <algorithm>
#define maxn 1005
#define inf 0x3f3f3f3f
using namespace std;

int a[maxn<<1];
int dp[maxn<<1][maxn<<1];          //dp[i][j] 表示区间[i,j]的最长非连续的回文串

int main()
{
	int n;
	while(scanf("%d", &n),n)
	{
		memset(dp, 0, sizeof(dp));
		for(int i=0; i<n; i++)
		{
			scanf("%d", &a[i]);
			a[n+i] = a[i];
		}
		//1个字符时,肯定是1了
		for(int i=0; i<2*n; i++)
			dp[i][i] = 1;
		for(int len=2; len<=2*n; len++)
			for(int i=0; i+len<2*n; i++)
			{
				int j = i+len-1;
				if(a[i]==a[j])
				{
					dp[i][j] = max(dp[i][j], dp[i+1][j-1]+2);
				}
				dp[i][j] = max(dp[i][j], max(dp[i+1][j], dp[i][j-1]));
			}
		int ans = 0;
		//n个字符
		for(int i=0; i<n; i++)
			ans = max(ans, dp[i][i+n-1]);
		//n-1个字符,最后一个当做公共的起点,所以+1
		for(int i=0; i<n; i++)
			ans = max(ans, dp[i][i+n-2]+1);
		printf("%d\n", ans);
	}
	return 0;
}


おすすめ

転載: blog.csdn.net/qq_31281327/article/details/76576421