题目链接
http://acm.hdu.edu.cn/showproblem.php?pid=4745
题解转自
https://my.oschina.net/u/4402652/blog/3524396
题目大意
给n个环状的数,A、B两个兔子沿相反的方向走,每次走一步,要求两个兔子每次到达的数要相同,(限制在一圈的范围内),问兔子最远能走几步。
解题思路
首先,把环倍增改成链,接下来找符合题意的最大步数
用dp[i][j]表示在区间[i,j]内,兔子能走的最大步数
初始化dp,预处理问题的子结构,如果a[i]==a[j] , dp[i][j]=dp[i+1][j-1]+2如果 a[i]!=a[j], dp[i][j]=max(dp[i+1][j],dp[i][j-1])
我把大佬题解里的这部分删了,我觉得任何情况下都要去判断 dp[i][j]=max(dp[i][j],max(dp[i+1][j],dp[i][j-1]))(对不住了大佬Orz,我不知道对不对,或许可以推出只有不等的时候才需要max俩dp)
最后输出最大步数,这里要考虑两种情况:
因为题目要求是:两个兔子往反方向走,并且要求范围限制在一圈之内。
1、如果两个兔子的开始起点不相同,那么每个兔子由起点i能走的最远位置为i+n-1;所以最后的结果是枚举dp[i][i+n-1]的最大值
2、如果开始起点相同,那么第一个起点肯定符合题目要求,跳过这个点直接从下一个点开始判断,最后的结果是枚举dp[i][i+n-2]+1的最大值
AC代码
#include<bits/stdc++.h>
using namespace std;
const int N=1e3+10;
int n;
int a[N<<1],dp[N<<1][N<<1];
int main(){
while(cin>>n&&n){
memset(dp,0,sizeof dp);
for(int i=1;i<=n;i++){
cin>>a[i];
a[i+n]=a[i];
dp[i][i]=1;
dp[i+n][i+n]=1;
}
for(int len=2;len<=n;len++)
for(int L=1;L+len-1<=n+n;L++){
int R=len+L-1;
if(a[L]==a[R]) dp[L][R]=dp[L+1][R-1]+2;
dp[L][R]=max(dp[L][R],max(dp[L+1][R],dp[L][R-1]));
}
int ans=0;
for(int i=1;i<=n;i++){//精髓
ans=max(ans,dp[i][i+n-1]);
ans=max(ans,dp[i][i+n-2]+1);
}
cout<<ans<<endl;
}
} 
京公网安备 11010502036488号