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]);
        }
    
    }
    
    
  • 相关阅读:
    Windows Server 2012配置开机启动项
    Windows Server 2019 SSH Server
    NOIP2017 senior A 模拟赛 7.7 T1 棋盘
    Noip 2015 senior 复赛 Day2 子串
    Noip 2015 senior复赛 题解
    Noip 2014 senior Day2 解方程(equation)
    Noip 2014 senior Day2 寻找道路(road)
    Noip 2014 senior Day2 无线网络发射器选址(wireless)
    Noip2014senior复赛 飞扬的小鸟
    Noip 2014 senior 复赛 联合权值(link)
  • 原文地址:https://www.cnblogs.com/a1439775520/p/13078572.html
Copyright © 2011-2022 走看看