poj2817状态压缩DP
2015-09-26 10:10
465 查看
//输出最大的与前一个字符相同的个数之和 //184K 0MS //主要要理解是状态压缩DP,状态是是否选择了该字符 //并且保存状态时候因为字符之间有顺序,所有需要保存最后一个字符 #include <iostream> #include <stdio.h> #include <string.h> using namespace std; #define MAXN 12 static int N; static char words[MAXN][MAXN]; static int len[MAXN][MAXN]; static int dp[1050][MAXN];//表示是否有该状态以及当前状态下最后一个字符 static int calcNums(int i,int j) { int k1,k2; k1 = k2 = 0; int len1 = strlen(words[i]); int len2 = strlen(words[j]); int ret = -1; for (k1=0;k1<len2;++k1) { int tmp = 0; int k3; for (k2=k1,k3=0;k2<len2&&k3<len1;++k2,++k3) if (words[i][k3]==words[j][k2])tmp++; if (tmp>ret) ret = tmp; } for (k1=0;k1<len1;++k1) { int tmp = 0; int k3; for (k2=k1,k3=0;k2<len1&&k3<len2;++k2,++k3) if (words[i][k2]==words[j][k3])tmp++; if (tmp>ret) ret = tmp; } return ret; } static void init() { memset(len,0,sizeof(len)); for (int i=0;i<N;++i) { for (int j=i+1;j<N;++j) { len[i][j] = len[j][i] = calcNums(i,j); } } } static void DP() { memset(dp,0,sizeof(dp)); for (int s=0;s<(1<<N)-1;++s) { for (int i=0;i<N;++i)//选择当前状态的最后一个字符 { if(s&(1<<i))//如果有该状态 for (int j=0;j<N;++j) { if (i!=j&&(s&(1<<j))==0) { dp[s|(1<<j)][j] = max(dp[s|(1<<j)][j],dp[s][i]+len[i][j]); } } } } int ans = 0; for (int i=0;i<N;++i) { if (dp[(1<<N)-1][i]>ans) ans = dp[(1<<N)-1][i]; } printf("%d\n",ans); } int main() { while(scanf("%d",&N)&&N) { for (int i=0;i<N;++i) scanf("%s",words[i]); init(); DP(); } return 0; }
相关文章推荐
- 动易2006序列号破解算法公布
- Ruby实现的矩阵连乘算法
- C#插入法排序算法实例分析
- 超大数据量存储常用数据库分表分库算法总结
- C#数据结构与算法揭秘二
- C#冒泡法排序算法实例分析
- C#使用DeflateStream解压缩数据文件的方法
- 算法练习之从String.indexOf的模拟实现开始
- C#算法之关于大牛生小牛的问题
- C#实现的算24点游戏算法实例分析
- C#调用WinRar执行rar、zip压缩的方法
- c语言实现的带通配符匹配算法
- 浅析STL中的常用算法
- 算法之排列算法与组合算法详解
- C++实现一维向量旋转算法
- Ruby实现的合并排序算法
- C#折半插入排序算法实现方法
- 基于C++实现的各种内部排序算法汇总
- C++线性时间的排序算法分析
- C++实现汉诺塔算法经典实例