• 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;
    }
    
    
  • 相关阅读:
    爬虫那些事儿---爬虫选择策略
    爬虫那些事儿--Http返回码
    【珍藏】linux 同步IO: sync、fsync与fdatasync
    perf学习-linux自带性能分析工具
    进程调度原理
    phpmyadmin 免登陆
    请为main函数提供返回值
    悬挂else引发的问题
    PhpMyAdmin导入数据库大小限制?
    linux内核Makefile整体分析
  • 原文地址:https://www.cnblogs.com/xuesu/p/14364985.html
Copyright © 2020-2023  润新知