CSU1620: A Cure for the Common Code(KMP+区间DP)

Description

Input

Output

Sample Input

abcbcbcbca
abbbcdcdcdabbbcdcdcd
0

Sample Output

Case 1: 7
Case 2: 11

HINT

Source

题意:把字符串简化,问简化得到的最短长度是多少

思路:要简化首先要求循环节,这里用kmp解决,而要求所有简化中最短的的话,用区间dp可以求得

<pre name="code" class="cpp">#include <iostream>
#include <stdio.h>
#include <string.h>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <vector>
#include <math.h>
#include <bitset>
#include <algorithm>
#include <climits>
using namespace std;

#define LS 2*i
#define RS 2*i+1
#define UP(i,x,y) for(i=x;i<=y;i++)
#define DOWN(i,x,y) for(i=x;i>=y;i--)
#define MEM(a,x) memset(a,x,sizeof(a))
#define W(a) while(a)
#define LL long long
#define N 505
#define MOD 19999997
#define INF 0x3f3f3f3f
#define EXP 1e-8

int dp[N][N],next1[N],cas = 1;
char s[N];

int kmp(char *s,int len)//kmp求循环节的长度
{
    next1[0] = next1[1] = 0;
    int i;
    UP(i,1,len-1)
    {
        int j = next1[i];
        W((j&&s[i]!=s[j]))
        {
            j = next1[j];
        }
        if(s[i]==s[j])
            next1[i+1]=j+1;
        else
            next1[i+1]=0;
    }
    return len-next1[len];
}

int getbit(int x)
{
    int cnt = 0;
    W(x)
    {
        x/=10;
        cnt++;
    }
    return cnt;
}

void DP()
{
    int n = strlen(s+1);
    int len,l,r,k,i;
    UP(i,1,n)
    dp[i][i]=1;
    UP(len,2,n)//区间dp求解最优值
    {
        for(l = 1; l+len-1<=n; l++)
        {
            r = l+len-1;
            dp[l][r]=dp[l][l]+dp[l+1][r];
            UP(k,l+1,r-1)
            {
                dp[l][r]=min(dp[l][r],dp[l][k]+dp[k+1][r]);
            }
            int t = kmp(s+l,len);
            if(len%t==0)//现在枚举的串是一个周期循环
            {
                int tem = dp[l][l+t-1];
                if(t>1) tem+=2;//因为不是一个字符的话要加括号
                tem+=getbit(len/t);//周期数
                dp[l][r]=min(tem,dp[l][r]);
            }
        }
    }
    printf("Case %d: %d\n",cas++,dp[1][n]);
}

int main()
{
    W(~scanf("%s",s+1))
    {
        if(s[1]=='0')
            break;
        DP();
    }

    return 0;
}
				
时间: 2024-10-18 07:02:41

CSU1620: A Cure for the Common Code(KMP+区间DP)的相关文章

CSU 1620: A Cure for the Common Code (区间DP KMP预处理)

链接 : http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1620 题意 : 给一个字符串 问怎么压缩字符串使得最终个数最小 具体怎么压缩请参照图示 很好明白. 题目就是需要找到 对于每个后缀 看成一个新字符串 找出它的前缀的最小循环节. 过程和大白书 P213页 是一样的,只需要对每个后缀跑一遍KMP求出周期. 剩下的过程就是区间DP了. dp[i][j] = min ( dp[i][k], dp[k+1][j] ); 如果i - j这一段存在

CSU 1620: A Cure for the Common Code(KMP+区间DP)

Description Input Output Sample Input abcbcbcbca abbbcdcdcdabbbcdcdcd 0 Sample Output Case 1: 7 Case 2: 11 HINT 题意:给一个小写子母的串,相邻相同的子串可以合在一起,问这个串合并后最短可得多长. 解题:KMP & 区间DP #include<stdio.h> #include<string.h> const int N = 505; int next1[N]; c

CodeForcesGym 100641B A Cure for the Common Code

A Cure for the Common Code Time Limit: 3000ms Memory Limit: 262144KB This problem will be judged on CodeForcesGym. Original ID: 100641B64-bit integer IO format: %I64d      Java class name: (Any) You've been tasked with relaying coded messages to your

The way of Webpack learning (II.) -- Extract common code(多页面提取公共代码)

学习之路基于webpack3.10.0,webpack4.0之后更新. 多页面提取公共代码!!! 一:文件关系 pageA --> subA.subB --> moduleA pageB --> subA.subB --> moduleA 那么pageA.pageB 的公共代码就是subA.subB .moduleA. 二:webpack.config.js文件配置 var webpack = require('webpack') var path = require('path'

A题:Common Substrings(KMP应用)

原题链接 注意:2号和3号get_next()函数中next[i]赋值时的区别,一个是0,一个是1,且不能互换 #include<cstdio> #include<cstring> #include<iostream> using namespace std; const int maxn=1e5+10; char ch[2*maxn]; char s[maxn],t[maxn]; int T,next[2*maxn]; /*1. void get_next(char

string (KMP+期望DP)

Time Limit: 1000 ms   Memory Limit: 256 MB Description  给定一个由且仅由字符 'H' , 'T' 构成的字符串$S$. 给定一个最初为空的字符串$T$ , 每次随机地在$T$的末尾添加 'H' 或者 'T' . 问当$S$为$T$的后缀时, 在末尾添加字符的期望次数. Input 输入只有一行, 一个字符串$S$. Output 输出只有一行, 一个数表示答案. 为了防止运算越界, 你只用将答案对$10^9+7$取模. Sample Inp

[LeetCode] Wildcard Matching 字符串匹配,kmp,回溯,dp

Implement wildcard pattern matching with support for '?' and '*'. '?' Matches any single character. '*' Matches any sequence of characters (including the empty sequence). The matching should cover the entire input string (not partial). The function p

hdu 1159(Common Subsequence)简单dp,求出最大的公共的字符数

Common Subsequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 23923    Accepted Submission(s): 10567 Problem Description A subsequence of a given sequence is the given sequence with some e

[HDU 3689]Infinite monkey theorem (KMP+概率DP)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3689 黄老师说得对,题目只有做wa了才会有收获,才会有提高. 题意:一个猴子敲键盘,键盘上有n个键,猴子敲第i个键的概率是p[i],问敲m次后形成的字符串里出现给定串的概率是多少. 这实际上就跟那个ac自动机转为trie图然后dp一样的. 类似的题目有POJ 2778,这篇题解不错:http://blog.csdn.net/luyuncheng/article/details/8643001 只不过