zoukankan      html  css  js  c++  java
  • Java实现 蓝桥杯VIP 算法训练 统计单词个数

    题目描述
    给出一个长度不超过200的由小写英文字母组 成的字母串(约定;该字串以每行20个字母的方式输入,且保证每行一定为20个)。要求将此字母串分成k份 (1< k< =40),且每份中包含的单词个数加起来总数最大(每份中包含的单词可以部分重叠。当选用一个单词之后,其第一个字母不能再用。例 如字符串this中可包含this和is,选用this之后就不能包含th)。
    单词在给出的一个不超过6个单词的字典中。
    要求输出最大的个数。

    数据规模和约定
    长度不超过200,1< k< =40,字典中的单词数不超过6。
    输入
    第一行有二个正整数(p,k)
    p表示字串的行数;
    k表示分为k个部分。
    接下来的p行,每行均有20个字符。
    再接下来有一个正整数s,表示字典中单词个数。(1< =s< =6)
    接下来的s行,每行均有一个单词。
    输出
    每行一个整数,分别对应每组测试数据的相应结果。
    样例输入
    1 3
    thisisabookyouareaoh
    4
    is
    a
    ok
    sab
    样例输出
    7

    import java.io.IOException;
    import java.util.HashSet;
    import java.util.Scanner;
    
    
    public class 统计单词个数 {
    	final static int Len = 200;
        final static int K = 40;
        static int p,k,n;
        static String s;
        static int dp[][];//dp[i][j]表示前i个字符,分成j个部分的话,最多能匹配多少个单词。
        static int mi[];//mi[i]表示s[i..mi[i]]能够和字典中的某个字符串匹配,且mi[i]是最小的
        static HashSet dic;
        
        //查找s[l..r]这个区间内有多少个字典中的字符串
        public static int get_num(int l,int r) {
            int ans = 0;
            for (int i = l;i <= r;i++)
                if (mi[i]<=r) {//最短的如果能匹配那么就ok,如果不行的话则说明以i开头没有字符串可以和字典匹配(至少在l..r这一段)
                    ans++;
                }
            return ans;
        }
            
        public static void main(String[] args) throws IOException{
            // TODO Auto-generated method stub
            Scanner in = new Scanner(System.in);
            p = in.nextInt();k = in.nextInt();
            dp = new int[Len+10][K+10];
            dic = new HashSet();
            mi = new int[Len+10];
            
            StringBuilder sb = new StringBuilder();
            sb.append(" ");
            for (int i = 1;i <= p;i++) {
                String temp;
                temp = in.next();
                sb.append(temp);
            }
            
            s = sb.toString();
            n = s.length()-1;
            
            p = in.nextInt();
            for (int i = 1;i <= p;i++) {
                String temp;
                temp = in.next();
                dic.add(temp);//把输入的单词加入到集合当中去
            }
            
            //处理出来mi数组
            for (int i = 1;i <= n;i++) {
                sb = new StringBuilder();
                mi[i] = 10000000;
                for (int j = i;j <= n;j++) {
                    sb.append(s.charAt(j));
                    if (dic.contains(sb.toString())) {//如果s[i..j]能够匹配,则说明mi[i]=j,因为j是顺序增长的
                        mi[i] = j;
                        break;
                    }
                }
            }
            for (int i = 1;i <= n;i++)
                for (int j = 0;j <= i-1;j++) {//枚举前一个状态的j
                    int cost = get_num(j+1,i);//获取j+1..i这一段有多少个单词
                    for (int l = 0;l <= Math.min(j, k);l++) {//枚举1..i这个字符串被分成了多少段
                        dp[i][l+1] = Math.max(dp[i][l+1],dp[j][l]+cost);//尝试更新状态
                    }
                }
            System.out.println(dp[n][k]);
        }
    
    }
    
    
  • 相关阅读:
    ZOJ 3765 Lights (zju March I)伸展树Splay
    UVA 11922 伸展树Splay 第一题
    UVALive 4794 Sharing Chocolate DP
    ZOJ 3757 Alice and Bod 模拟
    UVALive 3983 捡垃圾的机器人 DP
    UVA 10891 SUM游戏 DP
    poj 1328 Radar Installatio【贪心】
    poj 3264 Balanced Lineup【RMQ-ST查询区间最大最小值之差 +模板应用】
    【转】RMQ-ST算法详解
    poj 3083 Children of the Candy Corn 【条件约束dfs搜索 + bfs搜索】【复习搜索题目一定要看这道题目】
  • 原文地址:https://www.cnblogs.com/a1439775520/p/13079168.html
Copyright © 2011-2022 走看看