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]);
        }
    
    }
    
    
  • 相关阅读:
    Unique Binary Search Trees——LeetCode
    Binary Tree Inorder Traversal ——LeetCode
    Maximum Product Subarray——LeetCode
    Remove Linked List Elements——LeetCode
    Maximum Subarray——LeetCode
    Validate Binary Search Tree——LeetCode
    Swap Nodes in Pairs——LeetCode
    Find Minimum in Rotated Sorted Array——LeetCode
    Linked List Cycle——LeetCode
    VR AR MR
  • 原文地址:https://www.cnblogs.com/a1439775520/p/13078570.html
Copyright © 2011-2022 走看看