zoukankan      html  css  js  c++  java
  • luogu P1026 统计单词个数

    题目描述

    给出一个长度不超过 200 的由小写英文字母组成的字母串(该字串以每行 20 个字母的方式输入,且保证每行一定为 20 个)。要求将此字母串分成 k 份,且每份中包含的单词个数加起来总数最大。

    每份中包含的单词可以部分重叠。当选用一个单词之后,其第一个字母不能再用。例如字符串 this 中可包含 this 和 is,选用 this 之后就不能包含 th。

    单词在给出的一个不超过 6 个单词的字典中。

    要求输出最大的个数。

    输入格式

    每组的第一行有两个正整数 p,k . p 表示字串的行数,k 表示分为 k 个部分。

    接下来的 p 行,每行均有 20 个字符。

    再接下来有一个正整数 s 表示字典中单词个数。 接下来的 s 行,每行均有一个单词。

    输出格式

    1 个整数,分别对应每组测试数据的相应结果。

    输入输出样例

    输入
    1 3
    thisisabookyouareaoh
    4
    is
    a
    ok
    sab
    输出
    7


    【样例解释】 划分方案为 this / isabookyoua / reaoh


    • 此题第一个难点是意识到如果有两个字母同时符合要求, 最短的那个会更优(贪心).

    • 第二个难点是字符串的预处理. End[x]表示从x开始的最短的那个单词的最后一个字母的位置.如abcde里找ab单词, 那么End[1]=2.

    • 此题最难的部分是DP方程如何转移.

    • 我们假设DP[i][q]表示已经到了第i个字符, 如果此时在第i位字符后面砍第q刀,会得到的单词出现次数的总和.

    • 首先想到DP[i][q]从DP[j][q-1]来转移, 同时查找j+1到i位的单词个数. 但是 O(n3*k2), 会超.

    • 那么只好优化这个转化过程. 我们可以发现j+2到i位的单词个数可以算到j+1到i位的单词个数里面. 所以j采取倒序循环, 用一个t累计,从i一直到q

    (为啥是q, 你想啊, 你想砍第q刀是不是至少要从第q个字母开始枚举)

    代码如下

    #include<bits/stdc++.h>
    #define MN 1005
    #define Inf 0x3f3f3f3f
    #define ll long long
    using namespace std;
    int p,k,s,len,End[MN];
    ll dp[MN][45];
    string str;
    char Sen[MN];
    char Wor[11][MN];
    bool Find(int x,int y){
        string Cmp="";
        for(int i=x;i<=y;i++)Cmp+=Sen[i];
        for(int i=1;i<=s;i++)
    	if(string(Cmp)==string(Wor[i]+1))
        {
        return 1;
        }
        return 0;
    }
    void pre(int i){
         for(int j=i;j<=len;j++){
            if(Find(i,j)){
                End[i]=j;
                return;
            } 
         }
    }
    void Inp(){
    	memset(End,0x3f,sizeof(End));
    	cin>>p>>k;
    	len=p*20;
    	for(int i=1;i<=len;i++){
    		cin>>Sen[i];
    	}
    	cin>>s;
    	for(int i=1;i<=s;i++)
        	scanf("%s",Wor[i]+1);
        	
    }
    int main(){
    	
        Inp();
    	for(int i=1;i<=len;i++)
        	pre(i);
    	for(int i=1;i<=len;i++){
    	      for(int q=1;q<=k;q++){
                        int t=0;
    		       for(int j=i;j>=q;j--){
                     	if(End[j]<=i)
                               t++;
    	                 dp[i][q]=max(dp[i][q],dp[j-1][q-1]+t);
                     	
    		     }
                   }
    		
    	}
    	printf("%ld",dp[len][k]);
    	return 0;
    } 
    
  • 相关阅读:
    [转]对Lucene PhraseQuery的slop的理解
    Best jQuery Plugins of 2010
    15 jQuery Plugins To Create A User Friendly Tooltip
    Lucene:基于Java的全文检索引擎简介
    9 Powerful jQuery File Upload Plugins
    Coding Best Practices Using DateTime in the .NET Framework
    Best Image Croppers ready to use for web developers
    28 jQuery Zoom Plugins Creating Stunning Image Effect
    VS2005 + VSS2005 实现团队开发、源代码管理、版本控制(转)
    禁止状态栏显示超链
  • 原文地址:https://www.cnblogs.com/GUOGaby/p/13887463.html
Copyright © 2011-2022 走看看