题意:

给出字符串个数 n

给出n串字符串

找出上下两个字符串重复和最多的个数..

eg:

5
abc
bcd
cde
aaa
bfcde
0根据
aaa
abc
 bcd
  cde
bfcde答案就是重复的 a bc cd cde

思路:

因为状态很少..最多只有10 个字符串~而每个字符串最多 10 个字符..

所以可以用状态DP来实现..

dp[ sta ][ i ] 表示 在sta 状态下以第 i 串字符串结尾的最优解..

sta 用 (1<<n)-1 表示..其中变成二进制后1表示有这个状态 0 表示没有这个状态..

基本算法:

①. 根据给出的 n 确定 sta

②. 根据给出的数据确定辅助数组 f[ i ][ j ] 表示第 i 串接第 j 串的重复字符个数

③. 把dp 初始化为某一个值..表示不可达到的情况..

④. 给已知情况给dp 赋已知可达到情况的值..

⑤. for(i:1~sta)

  for(j: 0~n)

  if(i 中包含 j这个状态)

  for(k: 0~n)

  if(i 中不包含 k 这个状态)

  dp[state][ k ] = max/min(dp[state][k], dp[ i ][ j ] + f[ j ][ k ]) //实现dp的状态转移

⑤. 根据dp[sta][] 中的各种情况找出需要的答案~

Tips:

state = 2^n -1

for 循环中找的时候从 1 开始找~

还有对我来说就是 找出两个字符串重复的个数..

囧~我这个弱菜真的很纠结暴搜的过程吖~各种细节错..

※※

一些二进制的基本知识:

判断j是否属于集合i:i&(1<<j)

在集合i中去除j:i-(1<<j)或者i&(!(1<<j))  i^(1<<j)

在集合i中加入点j:i|(1<<j);

Code:

View Code

 1 #include <stdio.h>
 2 #include <cstring>
 3 #include <algorithm>
 4 using namespace std;
 5 #define clr(x) memset(x, 0, sizeof(x))
 6 #define max(a, b) (a)>(b)?(a):(b)
 7 const int INF = 0x1f1f1f1f;
 8
 9 int dp[1<<15][15], f[15][15];
10 char arr[15][15];
11
12 int lenn(char *a, char *b)
13 {
14     int lena = strlen(a), lenb = strlen(b);
15     int max = 0;
16     int sum;
17     for(int i = 0; i < lena; ++i){
18         sum = 0;
19         for(int j = 0; j < lenb && i+j < lena; ++j){
20             if(a[i+j] == b[j]) sum++;
21         }
22         if(sum > max) max = sum;
23     }
24
25     for(int i = 0; i < lenb; ++i){
26         sum = 0;
27         for(int j = 0; j < lena && i+j < lenb; ++j)
28             if(b[i+j] == a[j]) sum++;
29         if(sum > max) max = sum;
30     }
31     return max;
32 }
33
34 int main()
35 {
36     int i, j, k;
37     int n, st, sta;
38     while(scanf("%d", &n) != EOF)
39     {
40         if(n == 0) break;
41         clr(f), clr(dp);
42         st = (1<<n) - 1;
43
44         for(i = 0; i < n; ++i)
45             scanf("%s", arr[i]);
46
47         for(i = 0; i < n; ++i)
48         for(j = 0; j < n; ++j)
49         if(i != j){
50             f[i][j] = f[j][i] = lenn(arr[i], arr[j]);
51         }
52
53         memset(dp, -1, sizeof(dp));
54         for(i = 0; i < n; ++i)
55             dp[1<<i][i] = 0;
56
57         for(i = 1; i < st; ++i)
58         for(j = 0; j < n; ++j)
59         if(dp[i][j] != -1)
60             for(k = 0; k < n; ++k)
61             if(!(i&(1<<k))){
62                 sta = i+(1<<k);
63                 dp[sta][k] = max(dp[sta][k], dp[i][j]+f[j][k]);
64             }
65
66         int ans = 0;
67         for(i = 0; i < n; ++i)
68         if(dp[st][i] > ans) ans = dp[st][i];
69
70         printf("%d\n", ans);
71
72
73     }
74     return 0;
75 }

 

转载于:https://www.cnblogs.com/Griselda/archive/2012/09/07/2675948.html

POJ 2817 状态DP 字符串找最多的重复相关推荐

  1. UVA 11825 Hackers' Crackdown 状态DP

    题意: 有一个由编号0~n-1的n台计算机组成的网络,一共有n种服务,每台计算机上都运行着全部服务,对于每台计算机,你可以选择停止一项服务,这个行为会导致与这台计算机和与他相连的其他计算机上的这项服务 ...

  2. hdu 2809 状态DP 三国吕布

    参考于 http://blog.csdn.net/woshi250hua/article/details/7746780 题意:吕布一个人单挑N个英雄,没打一个英雄一定要有一个人死才行,求最后如何打才 ...

  3. poj 1947(树形dp+背包问题)

    题大意是:给你一棵节点为n的树,问至少砍几刀可以孤立出一棵节点为m的子树. 解题思路:这题很容易想到状态dp[i][j]表示以i节点为根,节点总数为j的子树最少需要切几刀.但是这个状态方程确实很难想, ...

  4. hdu 4529(状态dp)

    郑厂长系列故事--N骑士问题 Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others) P ...

  5. js比较两个String字符串找出不同,并将不同处高亮显示

    根据java代码改写成js,下边js文件代码: function StringBuffer() {this.__strings__ = []; }; StringBuffer.prototype.ap ...

  6. 2020牛客暑期多校训练营(第四场)H.Harder Gcd Problem(把1到n分为不互质的数对,找最多的对数)

    题目大意:把1到n分为不互质的数对,找最多的对数 思路:先从最大的质因数开始找,因为小的比大的更容易匹配,所以贪心的从大的开始找. 首先要预处理出所以数的最大质因数. 然后根据质因数从大往小找,当质因 ...

  7. 中文字符频率统计python_python统计字符串出现最多的字母及其出现次数

    统计字符串出现最多的字母及其出现次数 另外如果次数相同按字母顺序排序. 方法1 可以使用自定义键对c.most_common()进行排序,该键首先考虑频率的降序,然后考虑字母的降序(请注意lambda ...

  8. Fire (poj 2152 树形dp)

    Fire (poj 2152 树形dp) 给定一棵n个结点的树(1<n<=1000).现在要选择某些点,使得整棵树都被覆盖到.当选择第i个点的时候,可以覆盖和它距离在d[i]之内的结点,同 ...

  9. java异或-实现字符串找不同

    java异或实现字符串找不同 给定两个字符串 s 和 t,它们只包含小写字母. 字符串 t 由字符串 s 随机重排,然后在随机位置添加一个字母. 请找出在 t 中被添加的字母. 示例 1: 输入:s ...

最新文章

  1. IAB303 Data Analytics Assessment Task
  2. ansible的安装和使用
  3. 一文解读苹果 M1 芯片电脑上的开源软件
  4. (转)android Fragments详解三:实现Fragment的界面
  5. 牛客 - Sumo and Easy Sum(推公式+数学)
  6. android状态机是线程么,Java中的线程状态机 - java
  7. 对 Web 应用程序进行性能调优
  8. ps抠图头发丝 智能半径
  9. JavaScript是什么意思?
  10. 17110102_Windows系统下WebLogicServer12cR2安装详解
  11. 复变函数总结一:复变函数
  12. Navicat自动运行批处理作业并发送附件邮件
  13. Citrix桌面虚拟化基础搭建教程(持续更新)
  14. 激光干涉仪测量五轴机床旋转轴精度的方法
  15. vue中element中的input框和laod中防抖和节流结合使用(性能优化)使用lodash相关方法
  16. Mac 快速查找快捷键command+f失效解决办法
  17. 小学计算机管理员教学计划,小学教学计划汇总六篇
  18. FreeDOM —— 一个可迁移的网页信息抽取模型
  19. 1155芯片组H61/H67/P67/Z68的区别一览表
  20. 基于Python实现的全球新冠病毒数据分析

热门文章

  1. skip-gram模型介绍及代码
  2. Python——装饰器(二)
  3. php 扫描仪对接,Mac_Mac怎么连接扫描仪?苹果电脑Mac添加扫描仪教程,  有很多的用户需要用到扫 - phpStudy...
  4. GTJ2018如何导出全部工程量_工程遇到带E的钢筋应该如何处理?
  5. TENSORFLOW 指定使用GPU跑
  6. E: Malformed line 60 in source list /etc/apt/sources.list (dist parse)
  7. 解决Keras 与 Tensorflow 版本之间的兼容性问题,导入keras报错:module 'tensorflow.python.keras.backend' has no attribute
  8. 数据:Purpose以太坊ETF的持仓量达到4万枚ETH
  9. CentosNginx
  10. webpack 3 零基础入门教程 #6 - 使用 loader 处理 CSS 和 Sass