首页 > 代码库 > Best Sequence(poj 1699) 状压dp(TSP)

Best Sequence(poj 1699) 状压dp(TSP)

类似于前两天做的那个wordstack。状压的其实有时候爆搜+记忆化也差不多。

就是这个是要与之前的都重合,移位预处理要注意。

理解好第一个样例就行

/* ***********************************************
Author        :bingone
Created Time  :2014/12/9 22:48:56
File Name     :a.cpp
************************************************ */

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
#define  inf  0x3f3f3f3f
#define  maxn (10+10000)
using namespace std;
typedef long long ll;
int N,M,T;
char in[12][25];
int dp[1<<10][10];
int slen[10][10];
int len[10];
int main()
{
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
	scanf("%d",&T);
	while(T--){
		scanf("%d",&N);
		for(int i=0;i<N;i++)
			getchar(),scanf("%s",in[i]),len[i]=strlen(in[i]);
		memset(slen,0,sizeof(slen));
		for(int i=0;i<N;i++){
			for(int j=0;j<N;j++){
				if(i==j) continue;
				int tmp;
				for(int k=0;k<len[i];k++){
					tmp=0;
					if(len[i]<len[j]){
                        for(int t=len[j]-1,p=len[i]-1-k;t>-1 && p>-1;t--,p--)
                            if(in[i][p]!=in[j][t])break;
                            else tmp++;
                        if(tmp==len[i]-k) slen[i][j]=max(tmp,slen[i][j]);
					}
					else{
                        for(int t=len[j]-1,p=len[j]-1-k;t>-1 && p>-1;t--,p--)
                            if(in[i][p]!=in[j][t])break;
                            else tmp++;
					if(tmp==len[j]-k) slen[i][j]=max(tmp,slen[i][j]);
					}
				}
			}
		}
		int rt=1<<N;
		memset(dp,0x3f,sizeof(dp));
		for(int i=0;i<N;i++) dp[1<<i][i]=len[i];
		for(int i=0;i<rt;i++){
			for(int j=0;j<N;j++){
				if( (i&(1<<j))==0 ) continue;
				if(dp[i][j]==inf) continue;
				for(int k=0;k<N;k++){
					if(i&(1<<k)) continue;
					dp[i|(1<<k)][k]=min(dp[i|(1<<k)][k],dp[i][j]+len[k]-slen[j][k]);
					//printf("%d\n",(i&(1<<k)));
						}
			}
		}int ans=inf;
		for(int i=0;i<N;i++) ans=min(ans,dp[(1<<N)-1][i]);
		printf("%d\n",ans);
		}
    return 0;
}
/*
32ACCACC5TCGGGCAGCCGCGATCATCG3TACACTTACTG
ans:6 11 7 特别注意第一个样例的意思
*/


Best Sequence(poj 1699) 状压dp(TSP)