poj.3267

题目给定一个字典,并给定一个字符串,要求出使该字符串为字典中单词序列所必需删除的最少字符数。动态规划求解

下面简单分析一下:

令dp[i]为使message中第i+1个位置字符开始到message结束的字符串满足题目要求所删除的最少字符数。则动态转移方程如下:

dp[i]=min{dp[i+1]+1,dp[pivot]+pivot-i-len}

分析如下:

1)当第i个字符无法匹配时,则dp[i]=dp[i+1]+1;

2)否则,我们可以将其舍弃也可以匹配,故可以得到dp[i]=min{dp[i+1]+1,dp[pivot]+pivot-i-len}

综合1)2)可得到动态转移方程

下面详细分析一下什么叫匹配:

匹配即以该字符为首字符,并可以在该字符串中找到若干字符组合成一个在字典中出现的单词,则匹配

下面是代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define Max 610
#define Maxx 310
#define Min(a,b) (a)<(b)?(a):(b)
char dic[Max][30];
char message[Maxx];
int dp[Maxx];
int W,L;
int main(){
	scanf("%d%d",&W,&L);
	getchar();
	scanf("%s",message);
	getchar();
	for(int i=0;i<W;i++){
		scanf("%s",dic[i]);
		getchar();
	}
	dp[L]=0; // 初始化为0
	int pivot,index; // 迭代器
	for(int i=L-1;i>=0;i--){
		dp[i]=dp[i+1]+1; // 状态1
		for(int j=0;j<W;j++){ // 枚举每个单词,查看是否匹配
			pivot=i,index=0;
			int len=strlen(dic[j]); 
			while(pivot<L){ //此时匹配失败
				if(message[pivot]==dic[j][index]) //若相等则迭代器均增加
					pivot++,index++;
				else // 否则只增加message迭代器
					pivot++;
				if(index==len){  // 匹配成功
				    dp[i]=Min(dp[i],dp[pivot]+pivot-i-index); //状态2
				    break;
				}
			}
				
		}
	}
	printf("%d\n",dp[0]); // 输出结果
	return 0;
}


 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值