Online JudgeProblem SetAuthorsOnline ContestsUser
Web Board
Home Page
F.A.Qs
Statistical Charts
Problems
Submit Problem
Online Status
Prob.ID:
Register
Update your info
Authors ranklist
Current Contest
Past Contests
Scheduled Contests
Award Contest
User ID:
Password:
  Register

非严格证明的47msAC想法, 谁能证明我的对错? (绝非显摆...)

Posted by intheway at 2009-11-29 11:21:23 on Problem 1699 and last updated at 2009-11-29 11:27:03
看了这题一两天后都不知道怎么DP, 昨晚发热(应该不是H1N1)后突然想出如下方法...
首先预处理任意两字符串的最大相同长度
考虑生成所有的排列, 对每一个排列只允许当前字符串最多和前面一个字符串进行重叠, 并且是最大程度重叠.
非严格证明: 如果当前字符串应该和前面一个或者多个进行重叠, 那么在所有的排列中必然有将此字符串放到之前的位置, 也就是这种情况必然会被计算. 
另外如果当前字符串和前面一个字符串部分重叠, 最大程度的重叠与非最大程度的重叠产生的状态是一样的.
主要感觉是一段字符串被覆盖的先后没什么影响. 所以每次的附加代价就为当前字符串长度减去与前一个字符串的最大相同长度.
#include <iostream>
using namespace std;
const int INF = 1<<30;
const int MAXN = 30;
char s[MAXN][MAXN];
int n, w[MAXN][MAXN], len[MAXN];
bool used[MAXN];
int route[MAXN], minlen;

void calsame(int a, int b){
	int i, j, k;
	w[a][b] = 0;
	for(k = len[b]-1; k >= 0; --k){
		for(i = len[a]-k-1, j = 0; i < len[a]; ++i, ++j)
			if(s[a][i] != s[b][j])
				break;
		if(j == k+1){
			w[a][b] = k+1;
			break;
		}
	}	
}

void dfs(int dep, int curlen){
	if(dep == n){
		minlen = min(minlen, curlen);
		return ;
	}
	if(curlen >= minlen)	return ;
	for(int i = 0; i < n; ++i){
		if(used[i])	continue;
		used[i] = true;
		route[dep] = i;
		if(dep == 0)	dfs(dep+1, curlen+len[i]);
		else	dfs(dep+1, curlen+len[i]-w[route[dep-1]][i]);
		used[i] = false;
	}
}

void solve(){
	int i, j, k;
	for(i = 0; i < n; ++i)
		for(j = 0; j < n; ++j){
			calsame(i, j);
		}
	dfs(0, 0);
	printf("%d\n", minlen);
}
	
int main(){
//	freopen("in.txt", "r", stdin);	freopen("out.txt", "w", stdout);
	int T;
	scanf("%d", &T);
	while(T--){
		scanf("%d", &n);
		int i, j;
		for(i = 0; i < n; ++i){
			scanf("%s", s[i]);
			len[i] = strlen(s[i]);
		}
		minlen = INF;
		solve();
	} 
	return 0;
}

Followed by:

Post your reply here:
User ID:
Password:
Title:

Content:

Home Page   Go Back  To top


All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator