题目链接: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;
}
总结:
挺好的一道题,把一个看起来跟动态规划完全没关系的问题转成了动态规划,挺神奇的。