• POJ 3276 The Cow Lexicon DP 难度: 0


    题目

    http://poj.org/problem?id=3267

    题意

    有长为L的字符串(L<=600),现在问最少去掉多少个字符,使得字符串由字典中的词不重叠地构成。
    字典中含有k(k<=300)个词,每个词长度最多为25

    思路

    最粗暴的想法:假设当前已经匹配到i为第k个单词的结尾,向前找到第k个单词最早可以开始匹配的位置j,令dp为记载从字符串开始到当前位置完成字典匹配后去掉字符数目的最小值,那么明显dp[i] =dp[j] + i - j - words[k].size()

    感想

    1. TLE,原因是复杂度为O(300 * 300 * 600 * 25),所以后来直接用match从后往前匹配,去掉一重循环
    2. WA: 原因是忽略了字母匹配之后要向下走一个,恰好实例中单词又没有重复的字母。

    Code

    Mem:712K Time:1610MS

    #include <iostream>
    #include <cstring>
    #include <queue>
    using namespace std;
    int w, l;
    string words[601];
    char msg[301];
    int dp[301];
    int start_inds[601];
    int match(int end_ind, string word) {
    	int k = end_ind - 1;
    	for (int i = (int)word.size() - 1; i >= 0; i--, k--) {
    		while(k >= 0 && msg[k] != word[i]) k--;
    		if (i == 0)return k;
    	}
    	return -1;
    }
    int main() {
    	cin >> w >> l;
    	cin >> msg;
    	for (int i = 0; i <= l; i++) {
    		dp[i] = i;
    	}
    	for (int i = 0; i < w; i++) {
    		cin >> words[i];
    	}
    
    	for (int i = 0; i <= l; i++) {
    
    		for (int j = 0; j < i; j++) {
    			dp[i] = min(dp[i], dp[j] + i - j);
    		}
    		for (int k = 0; k < w; k++) {
    			if (words[k].size() > i)continue;
    
    			int largest_start_ind = match(i, words[k]);
    			start_inds[k] = largest_start_ind;
    			if (largest_start_ind >= 0 && dp[i] > dp[largest_start_ind] + i - largest_start_ind - (int)words[k].size()) {
    				dp[i] = dp[largest_start_ind] + i - largest_start_ind - (int)words[k].size();
    			}
    		}
    
    	}
    	cout << dp[l] << endl;
    	return 0;
    }
    
    
  • 相关阅读:
    基于Docker的Mysql主从复制搭建
    Docker操作命令——查看、停止、删除容器
    Git命令
    未定义数组下标: 0
    zookeeper-3.4.14单机多端口集群搭建
    使用MAT分析dump文件定位程序问题
    intellij idea2019.1中文破解版安装
    vscode打造golang开发环境
    python项目开发环境模块安装记录
    shell用法
  • 原文地址:https://www.cnblogs.com/xuesu/p/14364985.html
Copyright © 2020-2023  润新知