hihocoder1320 160周 压缩字符串

hihocoder1320

题目链接

思路:

dp解法。用map[i][j]表示从第i个开始到第j个的字串的best压缩长度。(包括i,j,两端闭合)。
用k表示i,j中的一点。
用zip()表示压缩i,j字串的函数,如果字串内部不能形成循环则返回字串长度。
map[i][j] =min{ zip(map[i][j]) , map[i][k] + map[k + 1][j]};

ac代码:

// hiho160week_yasuozifuchuan.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"

#include<iostream>
#include<cstdio>
#include<string>
#include<algorithm>
#include<vector>
using namespace std;

int map[101][101];

int countbits(int a)
{
	if (!a) return 1;
	int count = 0;
	while (a)
	{
		a /= 10;
		count++;
	}
	return count;
}

int zip(string s,int start,int end)
{
	if (start > end) return 0;
	int len = end - start + 1;
	if (len <= 4) return len;
	bool flag;
	for (int i = 1; i < len; i++)
	{
		if (len % i != 0) continue;
		flag = true;		
		for (int j = 0; j < i; j++)
		{
			for(int k = j + start; k + i <= end; )
			{
				if (s[k] != s[k + i])
				{
					flag = false;
					break;
				}
				k += i;
			}
			if (!flag) break;
		}
		if (flag)
		{
			return countbits(len / i) + map[start][start + i - 1] + 2;
		}
	}
	return len;
}

int main()
{
	int t;
	cin >> t;
	string s;
	while (t--)
	{
		cin >> s;
		int len = s.length();

		////initialize
		//for (int i = 0; i < len; i++)
		//{
		//	for (int j = i; j < len; j++)
		//	{
		//		map[i][j] = j - i + 1;
		//	}
		//}
		
		for (int i = len - 1; i >= 0; i--)
		{
			for (int j = i; j < len; j++)
			{
				map[i][j] = j - i + 1;
				if (j - i + 1 <= 4) continue;

				map[i][j] = min(map[i][j], zip(s, i, j));
				for (int k = i; k < j; k++)
				{
					map[i][j] = min(map[i][k] + map[k + 1][j], map[i][j]);
				}
			}
		}

		//for (int i = 0; i < len; i++)
		//{
		//	for (int j = 0; j < len; j++)
		//	{
		//		if (map[i][j])
		//			cout << map[i][j] << "	";
		//		else
		//			cout << " " << "	";
		//	}
		//	cout << endl;
		//}

		cout << map[0][len - 1] << endl;
		
	}
    return 0;
}


原文地址:https://www.cnblogs.com/weedboy/p/7239301.html