1 #include<iostream> 2 using namespace std; 3 4 #define SIZE 9 5 #define MAXLEN 6 6 int data[SIZE][MAXLEN]; 7 int numberLen[SIZE];//某一行有几位 8 int overlapLen[SIZE+1][SIZE+1];//某两位数的重叠长度 9 int maxLen=0; 10 int used[SIZE]; 11 12 void IToA(int N,int row)//数字转数组,并记录长度 13 { 14 int tmp=N; 15 int n=0; 16 while(tmp){ //统计位数 17 n++; 18 tmp/=10; 19 } 20 numberLen[row]=n; //位数信息放进数组 21 tmp=N; 22 for(int j=n-1;j>=0;j--) 23 { 24 data[row][j]=tmp%10; 25 tmp/=10; 26 } 27 } 28 29 void getOverlapLen(int i,int j)//计算两个数字的最小重叠长度,分前后,i在前,j在后 30 { 31 for(int len=1;len<=numberLen[i]&&len<=numberLen[j];len++)//遍历重合长度 32 { 33 int flag=1;//标志位 34 for(int m=numberLen[i]-len,n=0;m<numberLen[i]&&n<numberLen[j];m++,n++) 35 { 36 if(data[i][m]!=data[j][n]) 37 { 38 flag=0; 39 break; 40 } 41 } 42 if(flag) 43 { 44 overlapLen[i][j]=len; 45 break; 46 } 47 } 48 } 49 50 void getMaxLen(int step,int numbers,int curLen,int remainingLen,int preNumber) 51 { 52 if(step==numbers) return ;//出口 53 if(curLen+remainingLen-(numbers-step)+1<=maxLen) return;//预测长度剪枝 54 55 for(int i=0;i<numbers;i++)//全排列过程 56 { 57 if(!used[i]) 58 { 59 used[i]=1; 60 int tmpLen=curLen; 61 62 //关键代码,必须有 63 if(overlapLen[i][preNumber]==0&&step!=0)//只处理连接成功的情况 64 { 65 used[i]=0;//注意占位及恢复 66 continue; 67 } 68 69 curLen +=numberLen[i]-overlapLen[i][preNumber]; 70 if(maxLen<curLen) 71 maxLen=curLen; 72 getMaxLen(step+1,numbers,curLen,remainingLen-numberLen[i],i);//全排列的同时进行dfs 73 used[i]=0; //数据恢复 74 curLen=tmpLen; 75 } 76 } 77 } 78 79 int main() 80 { 81 freopen("input.txt","r",stdin); 82 int nTc; 83 cin>>nTc; 84 while(nTc--) 85 { 86 int N; 87 cin>>N; 88 89 //全局变量初始化 90 maxLen=0; 91 for(int i=0;i<SIZE;i++) 92 { 93 used[i]=0; 94 for(int j=0;j<MAXLEN;j++) 95 { 96 data[i][j]=0; 97 } 98 } 99 for(int i=0;i<=SIZE;i++) 100 { 101 for(int j=0;j<=SIZE;j++) 102 { 103 overlapLen[i][j]=0; 104 } 105 } 106 107 int temp; 108 int totalLen=0;//N个数总共有多少位 109 for(int i=0;i<N;i++) 110 { 111 cin>>temp; 112 IToA(temp,i); 113 totalLen+=numberLen[i]; 114 } 115 116 //求重合长度,数据预处理,可以处理极端的case 117 for(int i=0;i<N;i++) 118 { 119 for(int j=0;j<N;j++) 120 { 121 if(i!=j) 122 getOverlapLen(i,j); 123 } 124 } 125 126 getMaxLen(0,N,0,totalLen,SIZE); //step=0时,要求chongdie[i][prenum]=0 127 cout<<maxLen<<endl; 128 } 129 return 0; 130 }
原文:http://www.cnblogs.com/jintg/p/6347411.html