Ring hdu 2296

AC自动机+DP,这题尽量不要用string,我用string TLE了, string连接串时效率很低...


#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include    
#include 
#include   
#include  
#include 
#include     
#include 
#include    
#include 

using std::priority_queue;
using std::vector;
using std::swap;
using std::stack;
using std::sort;
using std::max;
using std::min;
using std::pair;
using std::map;
using std::string;
using std::cin;
using std::cout;
using std::set;
using std::queue;
using std::string;
using std::istringstream;
using std::make_pair;
using std::getline;
using std::greater;
using std::endl;
using std::multimap;

typedef long long LL;
typedef unsigned long long ULL;
typedef pair PAIR;
typedef multimap MMAP;

const int MAXN(1111);
const int SIGMA_SIZE(26);
const int MAXM(110);
const int MAXE(4000010);
const int MAXH(18);
const int INFI((INT_MAX-1) >> 2);
const int BASE(131);
const int MOD(20090717);
const ULL LIM(1000000000000000ull);

struct AC
{
	int ch[MAXN][SIGMA_SIZE];
	int val[MAXN];
	int f[MAXN];
	int size;
	
	void init()
	{
		memset(ch[0], 0, sizeof(ch[0]));
		f[0] = val[0] = 0;
		size = 1;
	}
	
	inline int idx(char temp)
	{
		return temp-'a';
	}
	
	void insert(char *S, int tv)
	{
		int u = 0, id;
		for(; *S; ++S)
		{
			id = idx(*S);
			if(!ch[u][id])
			{
				memset(ch[size], 0, sizeof(ch[size]));
				val[size] = 0;
				ch[u][id] = size++;
			}
			u = ch[u][id];
		}
		val[u] = tv;
	}
	
	int que[MAXN];
	int front, back;
	void construct()
	{
		front = back = 0;
		int cur, u;
		for(int i = 0; i < SIGMA_SIZE; ++i)
		{
			u = ch[0][i];
			if(u)
			{
				que[back++] = u;
				f[u] = 0;
			}
		}
		while(front < back)
		{
			cur = que[front++];
			for(int i = 0; i < SIGMA_SIZE; ++i)
			{
				u = ch[cur][i];
				if(u)
				{
					que[back++] = u;
					f[u] = ch[f[cur]][i];
					val[u] += val[f[u]];
				}
				else
					ch[cur][i] = ch[f[cur]][i];
			}
		}
	}
};

AC ac;

int table[2][MAXN];
char tstr[2][MAXN][60];
int tlen[2][MAXN];
/*
inline bool updata(string& s1, int &val1, const string &s2, const int &val2)
{
	if(val2 > val1)
	{
		val1 = val2;
		s1 = s2;
		return true;
	}
	if(val2 == val1 && (s2.size() < s1.size() || (s2.size() == s1.size() && s2 < s1)))
	{
		val1 = val2;
		s1 = s2;
		return true;
	}
	return false;
}
*/
void solve(int len)
{
	int cur = 0, last = 1;
	int ans = 0;
	char sans[60];
	int lans = 0;
	memset(table[last], -1, sizeof(table[last]));
	table[last][0] = 0;
	for(int i = 0; i < ac.size; ++i)
		tlen[last][i] = 0;
	for(int i = 0; i < len; ++i)
	{
		memset(table[cur], -1, sizeof(table[cur]));
		for(int j = 0; j < ac.size; ++j)
			tlen[cur][j] = 0;
		for(int j = 0; j < ac.size; ++j)
			if(table[last][j] >= 0)
				for(int k = 0; k < SIGMA_SIZE; ++k)
				{
					int ts = ac.ch[j][k];
					int t1 = table[last][j]+ac.val[ts];
					int &t2 = table[cur][ts];
					tstr[last][j][tlen[last][j]++] = 'a'+k;
					int tl1 = tlen[last][j];
					int &tl2 = tlen[cur][ts];
					if(t1 > t2 || (t1 == t2 && (tl1 < tl2 || (tl1 == tl2 && strncmp(tstr[last][j], tstr[cur][ts], tl1) < 0))))
					{
						t2 = t1;
						tl2 = tl1;
						strncpy(tstr[cur][ts], tstr[last][j], tl1);
						if(t2 > ans || (t2 == ans && (tl2 < lans || (tl2 == lans && strncmp(tstr[cur][ts], sans, tl2) < 0))))
						{
							ans = t2;
							lans = tl2;
							strncpy(sans, tstr[cur][ts], tl2);
						}
					}
					--tlen[last][j];
				}
		cur ^= 1;
		last ^= 1;
	}
	sans[lans] = '\0';
	printf("%s\n", sans);
}

char str[110][15];
int value[110];

int main()
{
	int TC;
	scanf("%d", &TC);
	while(TC--)
	{
		int len, M;
		scanf("%d%d", &len, &M);
		for(int i = 0; i < M; ++i)
			scanf("%s", str[i]);
		for(int i = 0; i < M; ++i)
			scanf("%d", value+i);
		ac.init();
		for(int i = 0; i < M; ++i)
			ac.insert(str[i], value[i]);
		ac.construct();
		solve(len);
	}
	return 0;
}






你可能感兴趣的:(训练指南,数据结构,动态规划,串)