HDU4745 Two Rabbits(區間dp)

Two Rabbits

傳送門1
傳送門2
Long long ago, there lived two rabbits Tom and Jerry in the forest. On a sunny afternoon, they planned to play a game with some stones. There were n stones on the ground and they were arranged as a clockwise ring. That is to say, the first stone was adjacent to the second stone and the n-th stone, and the second stone is adjacent to the first stone and the third stone, and so on. The weight of the i-th stone is ai.

The rabbits jumped from one stone to another. Tom always jumped clockwise, and Jerry always jumped anticlockwise.

At the beginning, the rabbits both choose a stone and stand on it. Then at each turn, Tom should choose a stone which have not been stepped by itself and then jumped to it, and Jerry should do the same thing as Tom, but the jumping direction is anti-clockwise.

For some unknown reason, at any time , the weight of the two stones on which the two rabbits stood should be equal. Besides, any rabbit couldn’t jump over a stone which have been stepped by itself. In other words, if the Tom had stood on the second stone, it cannot jump from the first stone to the third stone or from the n-the stone to the 4-th stone.

Please note that during the whole process, it was OK for the two rabbits to stand on a same stone at the same time.

Now they want to find out the maximum turns they can play if they follow the optimal strategy.

Input

The input contains at most 20 test cases.
For each test cases, the first line contains a integer n denoting the number of stones.
The next line contains n integers separated by space, and the i-th integer ai denotes the weight of the i-th stone.(1 <= n <= 1000, 1 <= ai <= 1000)
The input ends with n = 0.

Output

For each test case, print a integer denoting the maximum turns.

Sample Input

1
1
4
1 1 2 1
6
2 1 1 2 1 3
0

Sample Output

1
4
5

Hint

For the second case, the path of the Tom is 1, 2, 3, 4, and the path of Jerry is 1, 4, 3, 2.
For the third case, the path of Tom is 1,2,3,4,5 and the path of Jerry is 4,3,2,1,5.


題意

兩隻兔子在n塊圍成環形的石頭上跳躍,每塊石頭有一個重量值ai,一隻順時針跳一隻逆時針跳,每個時刻要求兩隻兔子所在石頭重量相同,兔子最多跳一圈(不回起點),問它們最多經過多少塊石頭.

分析

其實就是求一個環中,非連續最長迴文子序列的長度。
dp[i][j] = max(dp[i + 1][j], max(dp[i][j - 1], (a[i] == a[j] ? dp[i + 1][j - 1] + 2 : 0)));
當然這只是求出一個序列的非連續最長迴文子序列長度,而題目是
其實我們會發現可以把它當成一個鏈,然後切成兩半,求出兩邊的迴文長度,最大的和就是解。(這裏不用考慮起點問題,因爲兩邊的迴文中點都可以做起點 )

CODE

代碼其實很短

#include<cstdio>
#include<memory.h>
#define N 1005
#define FOR(i,a,b) for(int i=(a),i##_END_=(b);i<=i##_END_;i++)
int dp[N][N],a[N];
inline int  max(int x,int y) {return x>y?x:y;}
inline void Max(int&x,int y) {if(x<y)x=y;}
int main() {
    int n;
    while(scanf("%d",&n)&&n) {
        FOR(i,1,n)scanf("%d",&a[i]);
        memset(dp,0,sizeof dp);
        FOR(i,1,n)dp[i][i]=1;
        FOR(len,1,n-1)FOR(i,1,n-len) {
            int j=i+len;
            dp[i][j]=max(dp[i+1][j],max(dp[i][j-1],(a[i]==a[j]?dp[i+1][j-1]+2:0)));//狀態轉移
        }
        int ans=0;
        FOR(i,1,n)Max(ans,dp[1][i]+dp[i+1][n]);
        FOR(i,1,n)printf("dp[1][%d]=%d,dp[%d][%d]=%d\n",i,dp[1][i],i+1,n,dp[i+1][n]);
        printf("%d\n",ans);
    }
    return 0;
}





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