题目大意:
给定n 给定n个数
选定一个区间留下其他消去 要求区间两端的两个数一样
若成功留下一个区间 则在选定区间的基础上 继续进行上述操作
直到无法再选出这样的区间 求最多操作数
按区间长度由短到长DP
那么当 a[l]=a[r] , dp[l][r]=dp[l+1][r-1]+1
即 3 2 3 2 3 , dp[2][4]=dp[3][3]+1, dp[1][5] = dp[2][4]+1 这样就得到这个区间的最多操作数为2
而不等时 dp[l][r]=max(dp[l+1][r],dp[l][r-1]) 即在短区间找到一个较优的方案
#include <bits/stdc++.h> using namespace std; #define LL long long #define INF 0x3f3f3f3f #define mem(i,j) memset(i,j,sizeof(i)) #define inc(i,l,r) for(int i=l;i<=r;i++) #define dec(i,r,l) for(int i=r;i>=l;i--) #define gcd(i,j) __gcd(i,j); const int N=5e3+5; const int mod=1e9+7; const double eps=1e-8; int n,m,a[N]; int dp[N][N]; int main() { while(~scanf("%d",&n)) { inc(i,1,n) scanf("%d",&a[i]); inc(i,1,n) inc(j,1,n) dp[i][j]=0; inc(i,2,n) { inc(l,1,n-i+1) { int r=l+i-1; if(a[l]==a[r]) dp[l][r]=max(dp[l+1][r-1]+1,dp[l][r]); else dp[l][r]=max(dp[l+1][r],dp[l][r-1]); } } printf("%d ",dp[1][n]); } return 0; }