LightOJ 1422(区间DP)

题目链接:LightOJ 1422

解题思路:
其实一眼看过去根本没想到是DP,而是画了一个连线图,即两个相同数字之间连一条直线,要求的其实是一个最长不交错序列。后来想到了一种对称的情况,例如样例为”5 1 2 3 2 1”,这样就没解了。但是也因为想到了这种情况,提醒了我这是一道区间DP的题目,于是解法就很简单啦。

代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define INF 0x3f3f3f3f

using namespace std;

int n,dp[105][105],a[105];

int main()
{
    int T,t=0;
    scanf("%d",&T);
    while(t<T)
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
        }

        for(int i=1;i<=n;i++)
            for(int j=i;j<=n;j++)
                dp[i][j]=j-i+1;

        for(int i=1;i<n;i++)
            dp[i][i+1]=2-(a[i]==a[i+1]);        

        for(int l=2;l<n;l++)
        {
            for(int i=1;i<=n-l;i++)
            {
                if(a[i]==a[i+l])
                    dp[i][i+l]=dp[i+1][i+l-1]+1;
                for(int j=i;j<=i+l;j++)
                {
                    dp[i][i+l]=min(dp[i][i+l], dp[i][j]+dp[j][i+l]-1);
                }
            }
        }

        printf("Case %d: %d\n",++t,dp[1][n]);
    }

    return 0;
}

总结:
挺好的一道题,把一个看起来跟动态规划完全没关系的问题转成了动态规划,挺神奇的。

你可能感兴趣的:(LightOJ 1422(区间DP))