域名选择

题目链接: http://exercise.acmcoder.com/online/online_judge_ques?ques_id=3368&konwledgeId=40

解题思路: 首先,我们检查一下一个字符串是否在另一个字符串当中出现过,可以把出现过的字符串全都删除。

                  然后对于互相不包含的字符串,我们预处理出来每对字符串拼接在一起的最大可重叠部分是多少。

                 最后,可以暴力枚举每中可能的组合情况,计算最有答案。例如,有3个互不包含的字符串,那么存在的组合就是,123,132,213,231,312,321.

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 typedef long long LL;
 5 const int MAXN=100005;
 6 const LL MOD7 = 1e9+7;
 7 
 8 string s[15];
 9 int a[15][15];
10 int n;
11 
12 void solve()
13 {
14     int ans=10*1000;
15     vector<int> v;
16     for (int i=0;i<n;++i)
17     {
18         v.push_back(i);
19     }
20     int tmp=s[v[0]].length();
21     for (int i=1;i<n;++i)
22     {
23         tmp+=s[v[i]].length()-a[v[i-1]][v[i]];
24     }
25     ans=min(ans,tmp);
26     while (next_permutation(v.begin(),v.end()))
27     {
28         tmp=s[v[0]].length();
29         for (int i=1;i<n;++i) tmp+=s[v[i]].length()-a[v[i-1]][v[i]];
30         ans=min(ans,tmp);
31     }
32     printf("%d\n",ans);
33 }
34 int calCommonString(string a,string b)
35 {
36     // cout<<"cal: "<<a<<"\t"<<b<<endl;
37     int lena=a.length();
38     int lenb=b.length();
39     for (int i=min(lena,lenb)-1;i>=1;--i)
40     {
41         // cout<<"sub: "<<a.substr(lena-i,i)<<"\t"<<b.substr(0,i)<<endl;
42         if (a.substr(lena-i,i)==b.substr(0,i))
43             return i;
44     }
45     return 0;
46 }
47 
48 int main()
49 {
50 #ifndef ONLINE_JUDGE
51     freopen("test.txt","r",stdin);
52 #endif // ONLINE_JUDGE
53     scanf("%d",&n);
54     for (int i=0;i<n;++i) cin>>s[i];
55     int mask[15]{0};
56     for (int i=0;i<n;++i)
57     {
58         for (int j=i+1;j<n;++j)
59         {
60             if (s[i].find(s[j])!=-1) mask[j]=1;
61             if (s[j].find(s[i])!=-1) mask[i]=1;
62         }
63     }
64     int m=0;
65     for (int i=0;i<n;++i)
66         if (!mask[i]) s[m++]=s[i];
67     n=m;
68     // cout<<"n=m"<<n;
69     for (int i=0;i<n;++i)
70     {
71         for (int j=i+1;j<n;++j)
72         {
73             a[i][j]=calCommonString(s[i],s[j]);
74             a[j][i]=calCommonString(s[j],s[i]);
75         }
76     }
77 //    for (int i=0;i<n;++i) cout<<s[i]<<endl;
78 //    for (int i=0;i<n;++i)
79 //    {
80 //        for (int j=0;j<n;++j) cout<<a[i][j]<<" ";cout<<endl;
81 //    }
82     solve();
83     return 0;
84 }

 

转载于:https://www.cnblogs.com/djingjing/p/8978141.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值