poj3267

题意:给一个字符串,和一些单词,问最少去掉几个字母才能使文章都由那些单词组成。

思路:用动态规划来解决,去掉的字母等于总的长度减去匹配好的字母数。

因为匹配数比较好理解,所以用匹配数来解决的问题。

f( i )表示到第i个位置为止的最大匹配数,因为位置增加1的时候最多增加一个匹配的单词,

所以每次只检查一下每个位置匹配每个单词能给给匹配数带来的增量,

每次找到匹配字母增加数最大的就是这个位置为止的最优解。

动态规划式:

当该单词无法匹配的话:f( i )  = f(i - 1)

如果可以匹配的话f( i ) = max(f( t ) + 该单词的长度,f(i - 1))

(t表示字符串里对应匹配对应单词的前一个位置)


这道题特别应该注意的是字符串匹配的时候,一定要注意检查指针的移动。

刚开始就是因为指针移动的地方马虎贡献了一次WA。

#include<iostream> 
#include<Cstdio>
#include<string>
using namespace std; 

int dp[1000], length, size, i, j, k;
char word[1000];
char dic[800][30];
int dicLength[800];
int match(int pos, int num)
{
	int temp2 = pos, i, length1;
	char t1 = word[pos], t2 = dic[num][dicLength[num] - 1]; 
	if(t1 != t2)
		return -1;
	for(i = dicLength[num] - 1; i >= 0; i--)
	{
		t2 = dic[num][i];
		while(temp2 >= 0 && word[temp2] != t2)
		{
			if(word[temp2] == t2)
				break;
			temp2--;
		}
		
		if(temp2 == -1)
			return -1;
		if(i != 0)
			temp2--;
	}
	
	return temp2;
	
}
int main()  
{ 
	char *p; int max, temp, temp1;
	scanf("%d%d", &size, &length);
	scanf("%s", word);
	p = word;
	for(i = 0; i < size; i++)
	{
		scanf("%s", dic[i]);
		p = dic[i]; dicLength[i] = 0;
		while(*p != '\0')
		{
			p++;
			dicLength[i]++;
		}
	}
	
	dp[0] = 0;
	for(i = 1; i < length; i++)
	{
		max = dp[i - 1];
		for(j =0; j < size; j++)
		{
			temp = match(i, j);
			
			if(temp > -1)
			{
				//cout << temp << endl;
				if(temp == 0 && dicLength[j] > max)
					max = dicLength[j];
				else if(dicLength[j] + dp[temp - 1] > max)
					max = dicLength[j] + dp[temp - 1];
			}
		}
		dp[i] = max;
	}
	cout << length - dp[length - 1] << endl;
	return 0;
} 



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值