码迷,mamicode.com
首页 > 其他好文 > 详细

1029练习题 B 从头再来

时间:2019-10-30 23:05:19      阅读:143      评论:0      收藏:0      [点我收藏+]

标签:include   序列   不能   using   鬼才   多少   bbb   从头再来   code   

1029练习题 B 从头再来

KONO题面哒!

问题描述
WX2004作为一个非酋,玩什么都必须要用人海战术来堆死对面。这天他打开GFL,发现自己因为太菜太非被YM降级了。他对自己太菜这个事实感到十分懊悔,于是准备改过自新。他统计了自己以前拥有的人形和现在拥有的人形,并把他们按星级用字母编号,然后用一种不可描述的玄学方法排序得到了两个字符串s,t。现在他正在编队去打核心8,。由于他又菜又非,他只好把自己所拥有的人形(即t序列)按顺序分出k个组和铁血车轮战。但他太想念被降级之前的队伍,于是要求这k个队伍的字符串都能在原人形(即s序列)中找到并且顺序相同。现在他已经因抽不到陈自闭了,请你来帮他算出自己能塞多少个人形进队伍。
:按星级用字母编号即用a,b,c……来代替1,2,3……。由于此时的GFL经过了数次更新,所以不只有6个星级,有26个。)
题目大意:从s,t中选出k个不相交的连续的非空子串,保持每个子串在 s ,t中的相对位置顺序,使得每个相对的子串相同并求出所有子串长度和的最大值。给出的s,t中只有小写字母)
输入格式
第一行三个整数 n,m,k ,分别代表字符串 s,t 的长度,选出的子串的个数。
第二行一个字符串 s .
第三行一个字符串 t .

输出格式
一行一个整数,表示选出的子串长度之和的最大值。

样例输入
15 9 4
ababaaabbaaaabb
bbaababbb
样例输出
8

数据范围
\(n,m ≤ 1000,k ≤ 10\)


看得出来原题面的人都是鬼才


第一眼动归。然后我就打炸了。最后我交了个搜索,Wa0。

动归思路:

  • 状态:\(F[i][j][l][s]\)表示s序列中取到i号位,t序列中取到j号位,现在取了l组人形,第i,j号人选不选(0为必须选,1为可选可不选)
  • 状态转移方程:
    • \(s[i]!=t[j]\):\(f[i][j][l][1]=max(f[i-1][j][l][1],f[i][j-1][l][1])\)(都可选可不选并不能开新组,把上一个状态赋值过来)
    • \(s[i]=t[j]\):\(f[i][j][l][0]=f[i-1][j-1][l-1][1]+1\)(可以开新组)
      • 若此时:\(s[i-1]=t[j-1]\):\(f[i][j][l][0]=max(f[i][j][l][0],f[i-1][j-1][l][0]+1)\)(不开新组)
      • 判断完上一个条件后,\(f[i][j][l][1]=max(f[i][j][l][0],max(f[i-1][j][l][1],f[i][j-1][l][1]))\)(一般通过转移)
        (应该算是很好理解了吧……)

KONO代码哒!

#include<cstdio>
#include<iostream>
#include<cmath>
using namespace std;
int n,m,k;
char tmp[1010];
int f[1010][1010][11][2];
int a[1010],b[1010];
int main()
{
    scanf("%d%d%d",&n,&m,&k);
    int l,i,j;
    scanf("%s",tmp);
    for(i=1;i<=n;i++)a[i]=tmp[i-1]-'a';
    scanf("%s",tmp);
    for(i=1;i<=m;i++)b[i]=tmp[i-1]-'a';
    for(l=1;l<=k;l++)
    {
        for(i=1;i<=n;i++)
        {
            for(j=1;j<=m;j++)
            {
                if(a[i]==b[j]){
                    f[i][j][l][0]=f[i-1][j-1][l-1][1]+1;
                    if(a[i-1]==b[j-1]){
                        f[i][j][l][0]=max(f[i][j][l][0],f[i-1][j-1][l][0]+1);
                    }
                    f[i][j][l][1]=max(f[i][j][l][0],max(f[i-1][j][l][1],f[i][j-1][l][1]));
                }
                else f[i][j][l][1]=max(f[i-1][j][l][1],f[i][j-1][l][1]);
            }
        }
    }
    printf("%d\n",f[n][m][k][1]);
}

瞎改题面.jpg

1029练习题 B 从头再来

标签:include   序列   不能   using   鬼才   多少   bbb   从头再来   code   

原文地址:https://www.cnblogs.com/cooper233/p/11768172.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!