• 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;
    }
    
    
  • 相关阅读:
    paper:Exploiting Query Reformulations for Web Search Result Diversification
    Z3
    IDA pro 类型参考
    Angr包含什么
    Gcc编译选项
    Angr
    一张图系列之PLT-GOT
    ELF头文件
    BROP_轮子
    Pwn_
  • 原文地址:https://www.cnblogs.com/xuesu/p/14364985.html
Copyright © 2020-2023  润新知