• RQNOJ PID302 / [NOIP2001]统计单词个数 (动态规划)


    http://www.rqnoj.cn/problem/302

    题意:

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

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

    要求输出最大的个数。

    【思路】 先递推求出sum[i][j] 即从i到j 的区间里包含的的单词个数

                opt[i][j] 将1到j的区间 分成i分能得到的最多的单词数

                状态转移方程为opt[i][j]=max( opt[i-1][k]+sum[k+1][j] );

    #include<iostream>
    #include<stdio.h>
    #include<string.h>
    using namespace std;
    
    char ss[1002],s[10][202],sum[1002][1002],opt[1002][1002];
    int main()
    {
        int i,j,n,m,t,k,q;
        while(~scanf("%d%d",&n,&t))
        {
            getchar();
            for(i=0;i<n;i++)
                scanf("%s",ss+i*20+1);
            int len=strlen(ss+1);
            scanf("%d",&m);
            getchar();
            for(i=1;i<=m;i++)
                scanf("%s",s[i]);
    
            memset(sum,0,sizeof(sum));    //// sum[i][j]  把字符串 从i到j分 得到的最大的
    
            for(i=1;i<=len;i++)             //先得出 sum[i][i]
                for(j=1;j<=m;j++)
                {
                    int l=strlen(s[j]);
                    for( q=0;q<l&&i+q<=len;q++)
                        if(ss[i+q]!=s[j][q])
                            break;
                    if(q==l)
                    {
                        sum[i][i]=1;
                        break;
                    }
                }
                for(i=len-1;i>=1;i--)           //算其他的 sum[i][j]
                    for(j=i+1;j<=len;j++)
                    {
                        if(sum[i][i]==1)
                            sum[i][j]=sum[i+1][j]+1;
                        else 
                            sum[i][j]=sum[i+1][j];
                    }
                    ///////////////////////////////////////////////dp了!!
                    memset(opt,0,sizeof(opt));
                    for(i=1;i<=len;i++)
                        opt[1][i]=sum[1][i];             //opt[i][j] 将1到j 划分为 i个区间 得到的最大的 单词数
                    
    
                    for(i=2;i<=t;i++)
                        for(j=i;j<=len;j++)
                        {
                            for(k=i-1;k<=j-1;k++)
                                if(opt[i-1][k]+sum[k+1][j]>opt[i][j])
                                    opt[i][j]=opt[i-1][k]+sum[k+1][j];
                        }
                        printf("%d
    ",opt[t][len]);
    
    
    
            
        }
        return 0;
    }
    ///   

    实际上 这个wa80  现在还没找到哪里错了  先把代码放这里 找到了再贴上ac代码吧~~

  • 相关阅读:
    Tensorflow实战(二):Discuz验证码识别
    文竹越长越乱?教你7种修剪方法可保持文竹株形优美,矮壮浓密
    拼应需求分析
    软工实践结对第二次作业
    软工团队第一次作业--团队展示
    学习命令行传参
    软工实践第三次作业-原型设计
    软工实践第二次作业2.0
    软工实践第二次作业
    学习c++ofstream和ifstream
  • 原文地址:https://www.cnblogs.com/assult/p/3446416.html
Copyright © 2020-2023  润新知