poj2817 状态dp(二进制存储)+记忆化搜索

 http://www.cnblogs.com/PureMilk/archive/2008/07/17/1245085.html#2163586

   思想参考的这位的博客,写得很详细,十分感谢她(他),这也是我的第一道状态dp,代码是自己敲的,开始的时候,过不了样例,发现位运算的条件弄错了,还有num数组打表弄错了,改后就1A了。

上面的博客写得很详细,只稍微补充一下(补充在代码的注释中了),其它就看这个博客就行了。

/*
一个单词有就为1,没有就为0,于是用一个二进制序列存储哪些单词有或者没有,
将这个二进制序转化成十进制数,这样就用一个整数存储状态了
(此处单说有或者没有,可能会有点不好理解,下面会继续提到)
*/
#include <cmath>
#include <iostream>
using namespace std;

#define MAX(a, b) a>b?a:b

const int size = 11;
int num[size][size], dp[1050][size];
char word[size][size];
int len[size], n;

void calNum(int n, int m)
{
    int i, j, res1, res2, max1, max2;

	for(max1 = i = 0; i < len[n]; i++)
	{
		for(res1 = j = 0; j < len[m] && j + i < len[n]; j++)
			if(word[m][j] == word[n][j+i]) 
	             res1++;
		if(res1 > max1) max1 = res1;
	}		
    for(max2 = i = 0; i < len[m]; i++)
	{
		for(res2 = j = 0; j < len[n] && j + i < len[m]; j++)
			if(word[n][j] == word[m][j+i]) 
				res2++;
		if(res2 > max2) max2 = res2;
	}
    num[n][m] = num[m][n] = MAX(max1, max2);    
}

int dfs(int curr, int last)
{
    if(dp[curr][last] > 0)
		return dp[curr][last];
	if(curr == 0) return 0;
	
    int tmp, max = 0, next = (curr&(~(1<<last)));//将最后一个单词的状态变为0(即将有改成没有)
	
    for(int i = 0; i < n; i++)
		if( ((1<<i)&next) != 0 ) //判断第i个单词的状态是否为1,若为1则将其放在当前的最后一个单词前面
		{
		    tmp = dfs(next, i) + num[last][i];
			if(tmp > max) max = tmp;
		}
	return (dp[curr][last] = max);
}

int main()
{
	int i, j, state;

    while(scanf("%d", &n) && n > 0)
	{
		 memset(dp, 0, sizeof(dp));
		 state = (int)pow(2.0, n*1.0); 
		 /*state的值是表示所有单词都有的时候的状态的十进制整数加上1,
           例如:样例中5个单词都有的状态为11111,即31,而state为2的5次方,即32                  
		 */
         for(i = 0; i < n; i++)
		 {
			 scanf("%s", word[i]);
			 len[i] = strlen(word[i]);
		 }
         for(i = 0; i < n; i++)//打表num数组
            for(j = i+1; j < n; j++)
			    calNum(i, j);

		 int max = 0, tmp;
		 for(i = 0; i < n; i++)
		 {
			 tmp = dfs(state-1, i); //初始的时候,所有单词都有,所以初始状态为state-1
			 if(tmp > max)
		        max = tmp;
		 }
         printf("%d\n", max);
	}
	return 0;
}


 

 

你可能感兴趣的:(poj2817 状态dp(二进制存储)+记忆化搜索)