BZOJ 1032 JSOI 2007 祖码Zuma 区间DP

题目大意:依照祖玛的玩法(任意选颜色),给出一段区间。问最少用多少个球可以把全部颜色块都消除。


思路:把输入数据依照连续的块处理。保存成颜色和数量。然后用这个来DP。我们知道,一个单独的块须要两个同样的颜色能够消去,对于这种块f[i][i] = 2。其余的>=2个的块仅仅须要一个,这种块f[i][i] = 1。

转移就比較简单了,依照区间DP的一般思想,最外层循环的是区间长度。中间循环的是起始位置,最后循环的是松弛变量。

特殊情况是这个区间的两边是同一种颜色,多加一个转移方程。


CODE:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define MAX 510
using namespace std;

pair<int,int> arr[MAX];

int cnt,src[MAX],total;
int f[MAX][MAX];

int main()
{
	cin >> cnt;
	for(int i = 1; i <= cnt; ++i)
		scanf("%d",&src[i]);
	int last = src[1],num = 0;
	for(int i = 1; i <= cnt; ++i) {
		if(src[i] != last) {
			arr[++total] = make_pair(last,num);
			last = src[i];
			num = 1;
		}
		else	++num;
	}
	arr[++total] = make_pair(last,num);
	memset(f,0x3f,sizeof(f));
	for(int i = 1; i <= total; ++i)
		if(arr[i].second == 1)
			f[i][i] = 2;
		else	f[i][i] = 1;
	for(int k = 2; k <= total; ++k)
		for(int i = 1; i + k - 1 <= total; ++i)
		{
			if(arr[i].first == arr[i + k - 1].first)
				f[i][i + k - 1] = f[i + 1][i + k - 2] + (arr[i].second + arr[i + k - 1].second == 2 ?

1:0); for(int j = 1; j < k; ++j) f[i][i + k - 1] = min(f[i][i + k - 1],f[i][i + j - 1] + f[i + j][i + k - 1]); } cout << f[1][total] << endl; return 0; }



posted @ 2016-04-12 08:20  mfrbuaa  阅读(271)  评论(0编辑  收藏  举报