CTU OPEN 2017 Shooting Gallery /// 区间DP

题目大意:

给定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\n",dp[1][n]);
    }

    return 0;
}
View Code

 

posted @ 2019-03-17 14:55  _Jessie  阅读(109)  评论(0编辑  收藏  举报