Description

    众所周知,fang G 有很多小伙伴,有一天,Fang G 打算带他们去玩有趣的游戏OOXX,这个游戏需要分成两组,有趣的是,每个人互相之间都有一个满意度,大家都想和自己看重的人(excuse me???)一组,却又不希望和另一组拉开差距。
    Fang G
发现,每个队伍能发挥出的能力值和这个队伍之间满意值是相等的,而一个队伍之间满意值定义为每一个人对于这个队伍所有人(注意是所有人哦!!!)满意度总和的总和,而一个人对另外一个人的满意度和他们的名字是有关的,A对B的满意度定义为A名字前缀和B名字后缀的最长公共前缀(其实就是首x尾o相x连o辣)。
    而Fang G要做的就是如何分为两队,使得ooxx更加精彩!但是Fang G 现在有事情要做(是什么事情呢?),没办法完成分配工作,你现在就要帮他完成这个伟大的使命!使得两队在能力值差值最小的情况下,能力值较低的那一队满意度尽量高。

Input

第一行输入一个T代表测试数据的组数(T<=10)
接下来每组测试数据里:
第一行输入一个n代表待分队的人数(1<=n<=20)
接下来有n行,每行有一个字符串si代表每个人的姓名0<|si|<=10000

Output

对于每组测试数据,输出一行,从小到大输出两个数字分别代表两只队伍的能力值,两个数字之间用空格隔开

Sample Input

1
3
aab
bbc
cca

Sample Output

3 7

思路:KMP能求出互相之间的满意度。然后我们要遍历所有可能。遍历的复杂度O(2 ^ n),但是如果我们用n * n的复杂度去判断每一种情况每队的满意度会超时。我们可以用状压DP。显然一共1 << n种可能。我们从0开始往1 << n - 1判,最低位出现的1一定是新变化的,那么我就可以直接算出原来的情况+新增一个最低位的1,达到O(n)算出每队的满意度。

代码:

#include<set>
#include<map>
#include<cmath>
#include<queue>
#include<cstdio>
#include<vector>
#include<cstring>
#include <iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = + ;
const ull seed = ;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + ;
char s[][maxn];
int w[][];
int Next[maxn], len[maxn];
int dp[ << ];
int n;
void preKMP(int pos){
int i = , j = -;
Next[] = -;
while(i < len[pos]){
while(j != - && s[pos][i] != s[pos][j]) j = Next[j];
++i;++j;
Next[i] = j;
}
}
int KMP(int p, int str){
int i = , j = ;
while(i < len[str]){
while(j != - && s[p][j] != s[str][i]) j = Next[j];
++j;
++i;
if(i == len[str]) return j;
if(j >= len[p]){
j = Next[j];
}
}
return ;
}
int dis, ans1, ans2;
int main(){
int t;
scanf("%d", &t);
while(t--){
scanf("%d" ,&n);
for(int i = ; i < n; i++){
scanf("%s", s[i]);
len[i] = strlen(s[i]);
}
for(int i = ; i < n; i++){
preKMP(i);
for(int j = ; j < n; j++){
if(j == i){
w[i][j] = len[i];
continue;
}
w[i][j] = KMP(i, j);
}
} memset(dp, , sizeof(dp));
int mx = ( << n) - ;
for(int i = ; i <= mx; i++){
for(int j = ; j < n; j++){
if(i & ( << j)){
for(int k = j + ; k < n; k++){
if(i & ( << k)){
dp[i] += w[j][k] + w[k][j];
}
}
dp[i] += dp[i - ( << j)] + w[j][j];
break;
}
}
}
dis = INF;
ans1 = -INF, ans2 = -INF;
for(int i = ; i <= mx; i++){
if(abs(dp[i] - dp[mx ^ i]) < dis){
dis = abs(dp[i] - dp[mx ^ i]);
ans1 = min(dp[i], dp[mx ^ i]);
ans2 = max(dp[i], dp[mx ^ i]);
}
else if(abs(dp[i] - dp[mx ^ i]) == dis){
int r1 = min(dp[i], dp[mx ^ i]);
int r2 = max(dp[i], dp[mx ^ i]);
if(r1 > ans1){
ans1 = r2, ans2 = r2;
}
}
}
printf("%d %d\n", ans1, ans2);
}
return ;
}

FJNU Fang G and his Friends(状压DP)题解的更多相关文章

  1. Codeforces Gym 100610 Problem K. Kitchen Robot 状压DP

    Problem K. Kitchen Robot Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/10061 ...

  2. POJ 3254 - Corn Fields - [状压DP水题]

    题目链接:http://poj.org/problem?id=3254 Time Limit: 2000MS Memory Limit: 65536K Description Farmer John ...

  3. BZOJ 1087: [SCOI2005]互不侵犯King [状压DP]

    1087: [SCOI2005]互不侵犯King Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 3336  Solved: 1936[Submit][ ...

  4. ZOJ3802 Easy 2048 Again (状压DP)

    ZOJ Monthly, August 2014 E题 ZOJ月赛 2014年8月 E题 http://acm.zju.edu.cn/onlinejudge/showProblem.do?proble ...

  5. CF453B Little Pony and Harmony Chest (状压DP)

    CF453B CF454D Codeforces Round #259 (Div. 2) D Codeforces Round #259 (Div. 1) B D. Little Pony and H ...

  6. fzu2188 状压dp

    G - Simple String Problem Time Limit:2000MS     Memory Limit:32768KB     64bit IO Format:%I64d & ...

  7. loj 1316(spfa预处理+状压dp)

    题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=27024 题意:求0-(n-1)的经过最多的标记的点的最短路. 思路 ...

  8. HDU5816 Hearthstone(状压DP)

    题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=5816 Description Hearthstone is an online collec ...

  9. HDU 4568 Hunter 最短路+状压DP

    题意:给一个n*m的格子,格子中有一些数,如果是正整数则为到此格子的花费,如果为-1表示此格子不可到,现在给k个宝藏的地点(k<=13),求一个人从边界外一点进入整个棋盘,然后拿走所有能拿走的宝 ...

随机推荐

  1. docker命令汇总

    docker命令汇总 序号 类别 简述 命令 功能 说明 1 整体管理 安装 yum install docker-engine centos上安装docker Ubuntu上安装dockerapt- ...

  2. Python3学习之路~7.4 动态导入模块

    动态导入模块就是只知道str类型的模块名字符串,通过这个字符串导入模块. 准备: 首先创建一个模块目录lib,然后在目录内创建一个模块 aa.py: # aa.pyclass C: def __ini ...

  3. 基于Promise封装uni-app的request方法,实现类似axios形式的请求

    https://my.oschina.net/u/2428630/blog/3004860 uni-app框架中 安装(项目根目录下运行) npm install uni-request --save ...

  4. JMeter-正则表达式(Json中取value的部分值)

    2019-04-26问题:返回的json中提取短信验证码614930 { : "total":2, : "totalPage":1, : "rows& ...

  5. tensorflow training result

  6. 微软移除WIN10密码过期政策Microsoft Removes Password-Expiration Policy in Windows 10

    Microsoft this week announced a series of changes to the security baseline in Windows 10, including ...

  7. spring IOC 分析及实现

    什么是IOC Inversion of Control,控制反转,也成依赖倒置. 反转: 依赖对象的创建被反转,使用IOC之前,对象由自己创建,反转后,由IOC容器获取 IOC容器的工作: 负责创建, ...

  8. MongoDB基本信息

    一.MongoDB简介 来源:在2007年,由纽约一个叫10gen的创业团队开发,公司现在叫做MongoDB Inc,最初被开发为PAAS(平台即服务). 数据库类型:基于分布式文件存储的数据库.由C ...

  9. eclipse 没有web项目和server

    New项目中没有web Window菜单的preference没有server 解决方法:打开help->Install new software… 在work with中找到http://do ...

  10. ultiple Endpoints may not be deployed to the same path

    @Configurationpublic class WebSocketConfig { //打war包启动需要注释掉此:否则报 :DeploymentException: Multiple Endp ...