POJ 2817 WordStack 状态压缩DP 入门题
2013-08-29 10:33
411 查看
一些二进制的基本知识:
判断j是否属于集合i:i&(1<<j)
在集合i中去除j:i-(1<<j)或者i&(!(1<<j)) i^(1<<j)
在集合i中加入点j:i|(1<<j);
先预处理出len[i][j]表示第i个字符串与第j个字符串组合能匹配的最大字符数
用一个数的二进制来表示那些字符串,那些字符串还没有选,即二进制位为1 的表示已经选了,为0的表示还没有选
Dp[i][j]代表当选取的字符串为i状态,且最后一个选取的字符串是第j个字符串时的最优值
状态转移:枚举某个状态时,枚举一个已选的字符串(即当前状态二进制位为1的位),再枚举一个未选的字符串(当前状态二进制位为0的位),通过这两个字符串的拼接来更新拼接之后新的状态,因为加进了一个没在状态中的字符串,所以状态变成了 i|(1<<k) 假设i是当前枚举的状态,k是二进制位为0的位
所以状态转移就为
http://blog.csdn.net/accry/article/details/6607703
![](http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
View Code
判断j是否属于集合i:i&(1<<j)
在集合i中去除j:i-(1<<j)或者i&(!(1<<j)) i^(1<<j)
在集合i中加入点j:i|(1<<j);
先预处理出len[i][j]表示第i个字符串与第j个字符串组合能匹配的最大字符数
用一个数的二进制来表示那些字符串,那些字符串还没有选,即二进制位为1 的表示已经选了,为0的表示还没有选
Dp[i][j]代表当选取的字符串为i状态,且最后一个选取的字符串是第j个字符串时的最优值
状态转移:枚举某个状态时,枚举一个已选的字符串(即当前状态二进制位为1的位),再枚举一个未选的字符串(当前状态二进制位为0的位),通过这两个字符串的拼接来更新拼接之后新的状态,因为加进了一个没在状态中的字符串,所以状态变成了 i|(1<<k) 假设i是当前枚举的状态,k是二进制位为0的位
所以状态转移就为
dp[i|(1<<k)][k]=max(dp[i|(1<<k)][k],dp[i][j]+len[j][k]);
如果大家仔细观察一下代码中的关键转移部分,会发现:当我们要去更新dp[i|(1<<k)][k]状态时,dp[i][j]肯定已经是求好了的,在这道题目里dp[i][j]就是dp[i|(1<<k)][k]的子结构,每次都尝试着用dp[i|(1<<k)][k]的子结构去更新它
更多状态压缩的题目
http://blog.csdn.net/accry/article/details/6607703
![](http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
View Code
#include<stdio.h> #include<string.h> #define max(a,b)(a>b?a:b) int dp[1026][11]; int len[11][11]; int n; char str[11][11]; int main() { int n,i,j,k,x,count; int len1,len2,max; while(scanf("%d",&n),n) { memset(len,0,sizeof(len)); for(i=0;i<n;i++) scanf("%s",str[i]); for(i=0;i<n;i++){ for(j=0;j<n;j++){ if(i!=j) { max=-1;//pay attention len1=strlen(str[i]); len2=strlen(str[j]); for(k=0;k<len1;k++) { count=0; for(x=0;x<len2&&(x+k)<len1;x++) { if(str[i][x+k]==str[j][x]) count++; } if(count>max) max=count; } if(max>len[i][j]) len[i][j]=len[j][i]=max; } } } memset(dp,0,sizeof(dp)); for(i=0;i<(1<<n);i++) for(j=0;j<n;j++) { if(i&(1<<j))//if j is in the set of i { for(k=0;k<n;k++) { if(!(i&(1<<k)))//if k is not int the set of i,then process dp dp[i|(1<<k)][k]=max(dp[i|(1<<k)][k],dp[i][j]+len[j][k]); } } } max=-1; for(i=0;i<(1<<n);i++) for(j=0;j<n;j++) if(dp[i][j]>max) max=dp[i][j]; printf("%d\n",max); } return 0; }
相关文章推荐
- poj 2817 WordStack 【状态压缩DP】
- poj 2817 WordStack 状态压缩dp
- POJ 2817 WordStack(状态压缩DP)
- POJ 3254 Corn Fields 状态压缩dp入门
- poj 3254 Corn Fields【状态压缩dp】【入门第一题~~】
- POJ 2411 铺地砖 状态压缩dp入门
- Corn Fields POJ - 3254 状态压缩dp入门
- poj 3254 Corn Fields【状态压缩dp-入门】
- poj 3254 状态压缩dp入门题
- poj - 3254 Corn Fields (状态压缩dp入门)
- Corn Fields POJ - 3254(状态压缩dp入门)
- POJ 2817 WordStack 状态压缩DP 入门题
- 状态压缩DP poj 2817 WordStack 入门题
- POJ 3254 状态压缩DP入门
- Poj - 3254 Corn Fields (状态压缩dp入门第一题(详解
- 状态压缩dp入门题 POJ 1185 炮兵阵地
- 【状态压缩DP】【POJ3254】【POJ1185】 入门题
- 状态压缩dp入门[HDU1074][HDU1065][POJ3254][POJ1185][HDU4359][POJ3311][POJ2411]
- 【状态压缩dp 入门】POJ - 2411 Mondriaan's Dream
- POJ 2441 Arrange the Bulls(状态压缩DP入门)