poj1390

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int dp[250][250][250];
int v[250], kind[250];
int pre[250], last[250];
int p[250];
int n;
int nn;
int main()
{
	int times = 1;
	scanf("%d", &nn);
	for (int i = 1; i <= 200; i++)
		p[i] = i*i;
	while (nn--)
	{
		scanf("%d", &n);
		int tot = 0;
		int lastr = -1;
		for (int i = 1; i <= n; i++)
		{
			int a;
			scanf("%d", &a);
			
			if (a != lastr)
			{
				tot++;
				kind[tot] = a;
				v[tot] = 1;
			}
			else
				v[tot]++;
			lastr = a;
		}
		for (int i = 1; i <= n; i++)last[i] = 0;
		for (int i = 1; i <= tot; i++)
		{
			pre[i] = last[kind[i]];
			last[kind[i]] = i;
		}
		for (int i = 1; i <= tot; i++)
		{
			for (int j = i; j <= tot; j++)
			{
				for (int k = 0; k+v[j] <= n; k++)
					dp[i][j][k] = 0;
			}
		}
		for (int i = 1; i <= tot; i++)
		{
			for (int k = 0; k + v[i] <= n; k++)
			{
				dp[i][i][k] = p[k+v[i]];
			}
		}
		for (int len = 2; len <= tot; len++)
		{
			for (int i = 1; i + len - 1 <= tot; i++)
			{
				int r = i + len - 1;
					for (int k = 0; k + v[r] <= n; k++)
					{
						dp[i][r][k] = dp[i][r - 1][0] + p[v[r] + k];
						int prer = pre[r];
						while (prer >= i)
						{
							if (v[r] + v[prer] + k > n)
							{
								break;
							}
							if ((dp[i][prer][v[r] + k] + dp[prer + 1][r - 1][0]) > dp[i][r][k])
							{
								dp[i][r][k] = (dp[i][prer][v[r] + k] + dp[prer + 1][r - 1][0]);
								break;
							}
							prer = pre[prer];
						}
					}
					
			}
		}
		printf("Case %d: %d\n", times++, dp[1][tot][0]);
	}
}

猜你喜欢

转载自blog.csdn.net/guoshiyuan484/article/details/82685780
今日推荐