题意:
两只兔子,在n块围成一个环形的石头上跳跃,每块石头有一个权值ai,一只从左往右跳,一只从右往左跳,每跳一次,两只兔子所在的石头的权值都要相等,在一圈内(各自不能超过各自的起点,也不能再次回到起点)它们最多能经过多少个石头(1 <= n <= 1000, 1 <= ai <= 1000)。
题解:区间DP
首先分为两种情况:
1.两兔子在同一位置起跳。
2.两兔子在不同位置起跳。
分别对应原序列中长度为
n
的序列的最长回文子序列和长度为
一个序列的最长回文序列的DP:
dp[i][j]=max{dp[i−1][j],dp[i][j−1],(a[i]==[j])∗(dp[i+1][j−1]+2)}
。
#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
using namespace std;
const int Maxn=2050;
int n,a[Maxn],dp[Maxn][Maxn];
inline int Dp(int l,int r){
if(l>r)return 0;
if(dp[l][r])return dp[l][r];
if(l==r)return dp[l][r]=1;
dp[l][r]=max(Dp(l,r-1),Dp(l+1,r));
if(a[l]==a[r])dp[l][r]=max(dp[l][r],Dp(l+1,r-1)+2);
return dp[l][r];
}
int main(){
while(scanf("%d",&n),n){
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
}
memcpy(a+n+1,a+1,sizeof(int)*n);
memset(dp,0,sizeof(dp));
int ans=0;
for(int i=1;i<=n;i++)ans=max(ans,Dp(i,i+n-1));
for(int i=1;i<=n;i++)ans=max(ans,Dp(i,i+n-2)+1);
printf("%d\n",ans);
}
本文介绍了一个关于两只兔子在环形石头上跳跃的问题,并通过区间动态规划的方法求解两只兔子能在一圈内最多经过多少个石头。该问题分为两兔子在同一位置起跳和不在同一位置起跳两种情况。
3万+

被折叠的 条评论
为什么被折叠?



